设计模式读书笔记
设计模式一
来自《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
上一篇: Python3网络爬虫数据采集(多线程可爬取几十万新闻数据)
下一篇: 什么叫组合模式(设计模式)