• [设计模式]策略模式


    一、策略模式的定义与特点

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

    2、优点:

    • 类的行为被封装进一组类中,可以被轻易地扩充与改变,如果需要,甚至可以在运行时改变行为
    • 多重条件语句不易维护,使用策略模式可以避免使用多重条件语句。
    • 提供相同行为的不同实现,可以根据不同条件选择不同的行为。
    • 扩展性好,方便增加新的行为实现,不用修改原代码,只要增加即可。

    3、缺点:

    • 策略类数量可能会很多,每个策略都是一个类,复用的可能性小
    • 所有的策略类都要对外暴露

     

    二、策略模式满足的OO设计原则:

    1、找出应用中可能需要变化之处,把它们独立出来进行封装,不要和那些不需要变化的代码混在一起,这样做的好处是:一旦它真的变化了,只要更改相应部分即可,其他部分不会受到影响,这样代码变化引起的不经意后果变少,系统变得更有弹性。

    2、针对接口编程,而不是针对实现编程,即尽量将需要实现的功能/系统先进行抽象总结,形成接口,而具体的行为或者说实现部分作为可能会变化的部分,独立出来单独编码,一旦变化则其引起的后果会降低。

    3、多用组合,少用继承。

     

    三、策略模式的结构

    1、抽象策略类:定义了公共接口

    2、具体策略类:封装了具体的实现算法或行为,继承自抽象策略类

    3、上下文/环境:用来维护一个对抽象策略类的对象的引用

     

    四、策略模式的应用

    1、何时使用:一个系统有许多类,而区分它们的只是它们的行为时

    2、使用场景:算法或者说策略需要自由切换的场景;

    3、注意事项:如果一个系统的策略多于四个,需要考虑使用混合模式来解决策略类膨胀的问题

     

    五、具体实现(完整代码保存在github上)

    1、抽象策略类:定义公共接口

    public abstract class Duck{
        FlyBehavior flyBehavior;
        QuackBehavior quackBehavior;
        public Duck(){
        }
    
        public abstract void display();
    
        public void performFly(){
            flyBehavior.fly();
        }
        public void performQuack(){
            quackBehavior.quack();
        }
    
        public void swin(){
            System.out.println("All ducks float,even decoys!");
        }
    }
    

    2、具体策略类:封装具体的实现行为

    (1)封装鸭子叫的行为

    public class Quack implements QuackBehavior{
        public void quack(){
            System.out.println("Quack");
        }
    }
    

    (2)封装鸭子的飞行方式

    public class FlyWithWings implements FlyBehavior{
        public void fly(){
            System.out.println("I'm flying!");
        }
    }
    

    3、上下文/环境:维护对抽象策略类的引用

    public class MallardDuck extends Duck{
        public MallardDuck(){
            quackBehavior = new Quack();
            flyBehavior = new FlyWithWings();
        }
    
        public void display(){
            System.out.println("I'm a real Mallard duck");
        }
    }
    

    4、调用上述代码

    public class MiniDuckSimulator{
        public static void main(String[] args){
            Duck mallard = new MallardDuck();
            mallard.performQuack();
            mallard.performFly();
        }
    }

     最终的输出结果是: 

     

     

     

     

    参考资料

    [1] Head First 设计模式

    [2] https://www.cnblogs.com/adamjwh/p/11011095.html

  • 相关阅读:
    Linux基础操作
    MySQL基础常用指令
    String什么时候创建一个新对象?
    HashMap源码浅析
    LinkList源码浅析
    ArrayList源码浅析
    如何解决syntax error near unexpected token `fi'
    如何解决The request sent by the client was syntactically incorrect.
    Caused by: java.lang.IllegalArgumentException: Invalid <url-pattern> ajaxTest in servlet mapping
    CLUSTER cluster is down,redis报错
  • 原文地址:https://www.cnblogs.com/mj-selina/p/12446289.html
Copyright © 2020-2023  润新知