设计模式入门:
问题提出
开发一个鸭子应用
基于oo(面向对象: 封装 继承 多态 )
满足 新的需求新增 而且效率 很高 时间复杂度为O(n)
4、用OO原则解决新需求的不足
5、用策略模式来新需求解决
6、总结策略模式定义
一、开发一个鸭子应用
1、从项目"模拟鸭子游戏"开始
2、从OO的角度设计这个项目,鸭子超类,扩展超类:
子类例如有 绿🦆 红🦆
3、如果新增需求 ,鸭子可以飞
OO思维里的继承方式解决方案是:
4、难度增加
如果在更改一下 在原来飞的基础上加上 :某些鸭子不能飞 ;有些鸭子可以飞
如果还是用oo原则实现
所以 以上的方式 就不能满足了 ,需要一种新的设计方式
二 、 策略模式
新的设计方式应该保证 应对项目的扩展性,降低复杂度:
1)分析项目变化与不变部分,提取变化部分,抽象成接口+实现;
2)鸭子哪些功能是会根据新需求变化的?飞行。。。。
1、重新设计一下 这个游戏项目
public abstract class Duck {
// 在超类里面将接口对象放在这,在子类里面设定行为对象
Fly fly;
public Duck() { }
// 把之前飞写的方式改成 fly 接口对象的方法 由不同的实现类实现不同的算法逻辑
public void Fly() {
fly.dukeFly();
}
public abstract void display();
}
}
// -- 绿鸭子
public class GreenDuck extends Duck {
@Override
public void display() {
//实现基本属性
System.out.println("--gaga-- 叫");
}
// 在子类中给定他相对应的飞的属性
public GreenDuck() {
fly = new GoodFlyImpl();
}
}
// -- 红鸭子
public class RedDuck extends Duck {
@Override
public void display() {
System.out.println("--gege-- 叫");
}
// 在子类中给定他相对应的飞的属性
public GreenDuck() {
fly = new BadFlyImpl();
}
}
// 接口类
public interface Fly {
void dukeFly();
}
// 3)好处:新增行为简单,行为类更好的复用,组合更方便。既有继承带来的复用好处,没有挖坑
// 实现类 例如有的飞的好 、有的飞的不好
public class BadFlyImpl implements Fly {
@Override
public void dukeFly() {
System.out.println("坏的飞行方式");
}
}
// --------------------
public class GoodFlyImpl implements Fly {
@Override
public void dukeFly() {
System.out.println("好的飞行方式");
}
}
这样以抽象+接口的方式就能 满足以上问题 ,但是现在使用都是在构造函数里面使用不符合我们平时在代码里面写的
xxxDO xx = new xxxDO();的操作 我们可以优化一下
2、优化方案
在超类里面加上一个方法就可以自由调用了
public abstract class Duck {
// 在超类里面将接口对象放在这,在子类里面设定行为对象
Fly fly;
public Duck() { }
// 把之前飞写的方式改成 fly 接口对象的方法 由不同的实现类实现不同的算法逻辑
public void Fly() {
fly.dukeFly();
}
public abstract void display();
}
// 这样我们就可以在代码里方便使用了
public void SetMyFly(Fly myFly){
this.fly = myFly
}
}
4、测试
/**
* @Classname DukeMain
* @Description TODO
* @Date 2020-08-31 14:48
* @Created by buying
*/
public class DukeMain {
public static void main(String [] a){
//测试策略模式的接口
//1 . 在构造函数里面 调用
Duck green = new GreenDuck();
Duck red = new RedDuck();
System.out.println("****=绿头鸭行为=****");
green.display();
green.fly();
// 自由调用
green.SetMyFly(new GoodFlyImpl());
System.out.println("****==红头鸭行为==****");
red.display();
red.fly();
//red.SetMyFly(new BadFlyImpl());
System.out.println();
}
}
总结
策略模式:
(1).分别封装行为接口 (飞 、跑 、叫等), 实现算法族(即行为接口的实现),超类里面放行为接口对象,在 子类里面设定行为对象。
(2)策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到超类里面,从而避免代码重复。
(3)使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。
原则
分离变化部分,封装接口,基于接口编程各种功能。此模式让行为算法的变化独立于算法的使用者
举栗子:分离鸭子 能否飞行的功能以接口方式独立出来,如果有的鸭子可以飞行那就实现该行为接口
策略模式的缺点
①策略类数量增多,策略类数量增多,每一个策略都是一个类,复用的可能性很小,类数量增多。
②所有的策略类都需要对外暴露,上层模块必须知道有哪些策略,然后才能决定使用哪一个策略,这与迪米特法则是相违背的,可以使用工厂方法模式、代理模式修整这个缺陷。
(工厂| 代理)模式 后面会有所阐述
原文链接:
https://www.yuque.com/docs/share/e0ca5cb1-1e30-4c73-b16a-bab044b90f58?# 《策略模式》