欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

设计模式读书笔记

程序员文章站 2022-06-19 15:13:31
设计模式一来自《Head First 设计模式》读书笔记一个小白,欢迎大佬提出问题来打我脸,让我进步一点点策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。本章给出三个设计原则找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起针对接口编程,而不是针对实现编程多用组合,少用继承按照书中思路还原问题:这是一个鸭王类:#mermaid-svg-yYThrisDhRbj2t2G .label{font-fam...

设计模式一

来自《Head First 设计模式》读书笔记
一个小白,欢迎大佬提出问题来打我脸,让我进步一点点

策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

本章给出三个设计原则

  • 找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起
  • 针对接口编程,而不是针对实现编程
  • 多用组合,少用继承

按照书中思路还原问题:
这是一个鸭王类:

有很多鸭类继承了鸭王,为了满足市场需求,现在需要各种鸭提供一个服务来满足市场上阿姨的需求。
设计模式读书笔记
如果基于继承的思想,我们把这个新技能newSkill添加到鸭王类中,那么所有的鸭类都继承鸭王类的这个新技能,虽然我们可以在各个鸭类中覆盖鸭王的这个技能,使不同的鸭类拥有不能newSkill来满足市场需求,比如A鸭newSkill是颜值高,B鸭的newSkill是身材好等等等,但是以后还会加入别的鸭类,如果是一只纯洁鸭呢,一只周黑鸭呢,他可能不需要这个newSkill来满足市场需求。
设计模式读书笔记
鸭子的行为在子类里不断的改变,并且让所有的子类都有这些行为是不恰当的,有一个设计原则,出现的了

找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起。

“把会变化的部分取出并封装起来,以便以后可以轻易地改动或扩充次部分,而不影响不需要变化的其他部分。”
设计模式读书笔记
好了,说回鸭,我们知道Duck类内的fiy()和quack()会随着鸭子的不同而改变,为了要把这两个行为从Duck类中分开,我们将把他们从Duck类中取出来,建立一组新类来代表每个行为。
从现在开始,鸭子的行为将被放在分开的类中,此类专门提供某行为接口的实现。这样鸭子类就不在需要知道行为的实现细节。

针对接口编程,而不是针对实现编程

//创建飞行行为类必须实现的接口,以及两个行为实现类
public interface FlyBehavior {
	public void fly();
}
//所有的飞行行为类必须实现接口,你如果想飞,你也可以
public class Fly1 implements FlyBehavior {
	public void fly() {
		//第一种飞行方式
	}
}

public class Fly2 implements FlyBehavior {
	public void fly() {
		//第二种飞行方式
	}
}
//创建叫*行为类必须实现的接口,以及不同的行为实现类
public interface QuackBehavior {
	public void quack();
}
public class Quack1 implements QuackBehavior {
	public void quack() {
		//第一种叫*方式
	}
}
public class Quack2 implements QuackBehavior {
	public void quack() {
		//第二种叫*方式
	}
}

我们以及创建了两个行为类接口,以及几个接口的实现类,下面我们创建鸭王类

public abstract class Duck {
	//为行为接口类型声明两个引用变量
	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;

	public abstract void display();
	public void performFly() {
		flyBehavior.fly();
	}
	public void performQuack() {
		quackBehavior.quack();
	}
	public void swim() {
		System.out.println("不会游泳的鸭不配为鸭");
	}
}

在上面的这个Duck类中,声明了两个接口类型的引用变量,有一个抽象的描述方法,所以这个Duck类是抽象类,继承Duck类的子类都要实现这个方法。其余方法会被继承。
下面创建一个实验鸭

public class 实验鸭 extends Duck {
	public 实验鸭() {
		quackBehavior = new Quack1();
		flyBehavior = new Fly1();
	}
	public void display() {
		//必须要在子类中实现抽象方法
	}
}
//实验鸭在构造函数中,选择了叫*行为中的第一个实现类的方法
//飞行方法同上,如果实现方法中没有,我们只需要额外添加一个新的这个接口的实现类,然后调用就可以了,不会改变别的代码

测试

public class Test {
	public static void main (String[] args) {
		Duck d = new 实验鸭();
		d.performQuack();
		d.performFly();
	}
}

可不可以一会让实验鸭这样叫一会让实验鸭那样叫,这样是不是更能满足市场需求,这是根据不同客户需求定制不同叫*方法。
设计模式读书笔记
在Duck类中,加入个新方法

public void setQuackBehavior(QuackBehavior qb) {
	quackBehavior = qb;
}

这样通过设定方法,来设定鸭子的行为,而不是在鸭子的构造器内实例化,从此以后,可以随时调用这个方法来改变鸭子的叫*行为。

当市场有了新需求时候,你可以在写一个叫*方法的实现类,然后调用就可以了。

这种做法和“继承”不同的地方在于,鸭子的行为不是继承来的,而是和适当的行为对象“组合”来的。

多用组合,少用继承

使用组合建立系统具有很大的弹性,不仅可将算法族封装成类,更可以“在运行时动态地改变行为”,只要组合的行为对象符合正确的接口标准即可。

书上说:如果连写一个“HelloWorld”都能够扯上模式,那就说明你以及病了,得看。。。

本文地址:https://blog.csdn.net/m0_51283856/article/details/109277175