当前位置: 移动技术网 > IT编程>软件设计>设计模式 > 设计模式读书笔记

设计模式读书笔记

2020年10月25日  | 移动技术网IT编程  | 我要评论
设计模式一来自《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

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网