Java设计者模式之策略模式
从模拟一个鸭子项目开始
我们从面向对象的角度来设计鸭子超类,扩展超类
鸭子超类
/**
* @Author:cbx
* @Date:2020/10/12/15:59
*/
public abstract class Duck {
public Duck(){
}
public void Quack(){
System.out.println("ga");
}
public abstract void display();
public void swim(){
System.out.println("swim");
}
}
绿头鸭
/**
* @Author:cbx
* @Date:2020/10/13/12:02
*/
public class GreenHeadDuck extends Duck {
@Override
public void display() {
System.out.println("greenDuck");
}
}
红头鸭
/**
* @Author:cbx
* @Date:2020/10/13/12:04
*/
public class RedHeadDuck extends Duck {
@Override
public void display() {
System.out.println("redHead");
}
}
测试类
1. @Author:cbx
2. @Date:2020/10/13/12:05
*/
public class testDemo1 {
public static void main(String[] args) {
GreenHeadDuck greenHeadDuck=new GreenHeadDuck();
RedHeadDuck redHeadDuck=new RedHeadDuck();
greenHeadDuck.display();
greenHeadDuck.Quack();
greenHeadDuck.swim();
redHeadDuck.display();
redHeadDuck.Quack();
redHeadDuck.swim();
}
}
测试结果
项目新需求
- 添加会飞的鸭子
我们可以想到在鸭子的超类里添加一个fly方法,来达到拓展
package Mode.Strategies;
/**
* @Author:cbx
* @Date:2020/10/12/15:59
*/
public abstract class Duck {
public Duck(){
}
public void Quack(){
System.out.println("ga");
}
public abstract void display();
public void swim(){
System.out.println("swim");
}
public void fly(){
System.out.println("fly");
}
}
新问题(不是所有的都会飞)
放在超类里的fly方法显然是不合适的
暴露出继承的问题
对类的局部改动,尤其是超类的局部改动,会影响子类
初步解决方案,子类覆盖fly方法
让不会飞的鸭子覆盖掉fly方法
但是如果有100个不会飞的就要改动100次,显然不合理
package Mode.Strategies;
/**
* @Author:cbx
* @Date:2020/10/13/12:02
*/
public class GreenHeadDuck extends Duck {
@Override
public void display() {
System.out.println("greenDuck");
}
@Override
public void fly() {
System.out.println("no fly");
}
}
又来新需求石头鸭子
不会飞,不会叫,我们在原本的代码上又要进行很多的改动
超类挖的坑,每个子类都要来填
用策略模式解决新需求
好处:新增行为简单,形成类的更好复用,组合也方便,比如会叫不会飞的鸭子。。。。。
- 分析项目的变化与不变化部分,将变化的部分,抽象成接口+实现
- 假设鸭子的叫声和飞行是根据鸭子不同来变化的
定义接口
飞行接口
/**
* @Author:cbx
* @Date:2020/10/13/12:26
*/
public interface FlyBehavior {
void fly();
}
接口的行为组
/**
* @Author:cbx
* @Date:2020/10/13/12:30
*/
public class NoFly implements FlyBehavior {
@Override
public void fly() {
System.out.println("noFly");
}
}
package Mode.Strategies;
/**
* @Author:cbx
* @Date:2020/10/13/12:30
*/
public class GoodFly implements FlyBehavior {
@Override
public void fly() {
System.out.println("goodFly");
}
}
叫声接口
/**
* @Author:cbx
* @Date:2020/10/13/12:26
*/
public interface QuackBehavior {
void Quack();
}
接口的行为组
package Mode.Strategies;
/**
* @Author:cbx
* @Date:2020/10/13/12:34
*/
public class NoQuack implements QuackBehavior {
@Override
public void Quack() {
System.out.println("no quack");
}
}
package Mode.Strategies;
/**
* @Author:cbx
* @Date:2020/10/13/12:34
*/
public class GoodQuack implements QuackBehavior {
@Override
public void Quack() {
System.out.println("good quack");
}
}
重新设计超类
package Mode.Strategies.next;
/**
* @Author:cbx
* @Date:2020/10/13/12:37
*/
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck(){}
public void Fly(){
flyBehavior.fly();
}
public void Quack(){
quackBehavior.Quack();
}
public abstract void display(); //留给子类来实现
}
重新定义子类
package Mode.Strategies.next;
/**
* @Author:cbx
* @Date:2020/10/13/12:40
*/
public class GreenHeadDuck extends Duck {
//假设是会飞不会叫的鸭子
public GreenHeadDuck(){
flyBehavior=new GoodFly();
quackBehavior=new NoQuack();
}
@Override
public void display() {
System.out.println("。。。自定义");
}
}
总结策略模式
分别封装行为接口,实现算法族,超类里放行为接口对象,在子类里具体设定行为对象。原则是:分离变化部分,封装接口,基于接口编程各种功能。
此模式让行为算法的变化独立算法的使用者。
本文记录自极客的java设计模式