zoukankan      html  css  js  c++  java
  • 《Head First 设计模式》:策略模式

    正文

    一、定义

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

    要点:

    • 策略模式把系统中会变化的部分抽出来封装。

    二、实现步骤

    1、创建策略接口

    /**
     * 策略接口
     */
    public interface Strategy {
    
        /**
         * 执行策略行为
         */
        public void perform();
    }
    

    2、创建策略接口的实现类

    (1)策略实现类 A

    /**
     * 策略实现类A
     */
    public class StrategyImplA implements Strategy {
    
        /**
         * A策略行为
         */
        @Override
        public void perform() {
            System.out.println("perform A...");
        }
    }
    

    (2)策略实现类 B

    /**
     * 策略实现类B
     */
    public class StrategyImplB implements Strategy {
    
        /**
         * B策略行为
         */
        @Override
        public void perform() {
            System.out.println("perform B...");
        }
    }
    

    3、在使用策略的类中,声明并使用接口类型的策略变量

    /**
     * 策略使用者
     */
    public class StrategyUser {
        
        /**
         * 声明接口类型的策略变量
         */
        private Strategy strategy;
        
        /**
         * 通过构造实例化策略
         */
        public StrategyUser(Strategy strategy) {
            this.strategy = strategy;
        }
    
        /**
         * 执行策略使用者的行为
         */
        public void doBehavior() {
            // do something...
            
            // 使用策略
            strategy.perform();
            
            // do something...
        }
    }
    

    4、通过实例化不同的策略实现类,来改变使用者的行为

    public class Test {
        
        public static void main(String[] args) {
            // 使用策略A
            StrategyUser userA = new StrategyUser(new StrategyImplA());
            userA.doBehavior();
            // 使用策略B
            StrategyUser userB = new StrategyUser(new StrategyImplB());
            userB.doBehavior();
        }
    }
    

    三、举个栗子

    1、背景

    Joe 上班的公司做了一套相当成功的模拟鸭子游戏:SimUDuck。游戏中会出现各种鸭子,鸭子的种类及属性如下:

    • 种类:绿头鸭、红头鸭、橡皮鸭、诱饵鸭。
    • 属性:外观、游泳行为、飞行行为、呱呱叫行为(叫声)。

    不同种类的鸭子所对应的属性如下:

    • 绿头鸭:绿头鸭的外观、会游泳、会飞行、呱呱叫。
    • 红头鸭:红头鸭的外观、会游泳、会飞行、呱呱叫。
    • 橡皮鸭:橡皮鸭的外观、会游泳(漂浮)、不会飞行、吱吱叫。
    • 诱饵鸭:诱饵鸭的外观、会游泳(漂浮)、不会飞行、不会叫。

    2、要点

    • 由于不同种类的鸭子可能具有不同的飞行行为、呱呱叫行为,因此,可以使用策略模式把这两种行为抽出来。

    3、实现

    (1)创建行为接口

    /**
     * 飞行行为接口
     */
    public interface FlyBehavior {
    
        public void fly();
    }
    
    /**
     * 呱呱叫行为接口
     */
    public interface QuackBehavior {
    
        public void quark();
    }
    

    (2)实现行为接口

    /**
     * 用翅膀飞行
     */
    public class FlyWithWings implements FlyBehavior {
    
        @Override
        public void fly() {
            System.out.println("I'm flying!");
        }
    }
    
    /**
     * 不会飞行
     */
    public class FlyNoWay implements FlyBehavior {
    
        @Override
        public void fly() {
            System.out.println("I can't flying!");
        }
    }
    
    /**
     * 呱呱叫
     */
    public class Quack implements QuackBehavior {
    
        @Override
        public void quark() {
            System.out.println("Quack");
        }
    }
    
    /**
     * 吱吱叫
     */
    public class Squeak implements QuackBehavior {
    
        @Override
        public void quark() {
            System.out.println("Squeak");
        }
    }
    
    /**
     * 不会叫
     */
    public class MuteQuack implements QuackBehavior {
    
        @Override
        public void quark() {
            System.out.println("<<Silence>>");
        }
    }
    

    (3)创建鸭子抽象类,并使用行为接口

    /**
     * 鸭子抽象类
     */
    public abstract class Duck {
        
        FlyBehavior flyBehavior;
        QuackBehavior quackBehavior;
        
        public Duck() {
        }
        
        /**
         * 外观
         */
        public abstract void display();
    
        /**
         * 游泳行为
         */
        public void swim() {
            System.out.println("All ducks float, even decoys!");
        }
        
        /**
         * 飞行行为
         */
        public void performFly() {
            flyBehavior.fly();
        }
        
        /**
         * 呱呱叫行为
         */
        public void performQuark() {
            quackBehavior.quark();
        }
    }
    

    (4)创建鸭子子类,并指定具体的行为实现

    /**
     * 绿头鸭
     */
    public class MallardDuck extends Duck {
        
        public MallardDuck() {
            // 指定具体的飞行行为
            flyBehavior = new FlyWithWings();
            // 指定具体的呱呱叫行为
            quackBehavior = new Quack();
        }
    
        @Override
        public void display() {
            System.out.println("I'm a real Mallard duck");
        }
    }
    
    /**
     * 红头鸭
     */
    public class RedHeadDuck extends Duck {
        
        public RedHeadDuck() {
            // 指定具体的飞行行为
            flyBehavior = new FlyWithWings();
            // 指定具体的呱呱叫行为
            quackBehavior = new Quack();
        }
    
        @Override
        public void display() {
            System.out.println("I'm a red head duck");
        }
    }
    
    /**
     * 橡皮鸭
     */
    public class RubberDuck extends Duck {
        
        public RubberDuck() {
            // 指定具体的飞行行为
            flyBehavior = new FlyNoWay();
            // 指定具体的呱呱叫行为
            quackBehavior = new Squeak();
        }
    
        @Override
        public void display() {
            System.out.println("I'm a rubber duck");
        }
    }
    
    /**
     * 诱饵鸭
     */
    public class DecoyDuck extends Duck {
        
        public DecoyDuck() {
            // 指定具体的飞行行为
            flyBehavior = new FlyNoWay();
            // 指定具体的呱呱叫行为
            quackBehavior = new MuteQuack();
        }
    
        @Override
        public void display() {
            System.out.println("I'm a decoy duck");
        }
    }
    

    (5)测试

    public class Test {
        
        public static void main(String[] args) {
            // 绿头鸭
            MallardDuck mallardDuck = new MallardDuck();
            mallardDuck.performFly();
            mallardDuck.performQuark();
            // 红头鸭
            RedHeadDuck redHeadDuck = new RedHeadDuck();
            redHeadDuck.performFly();
            redHeadDuck.performQuark();
            // 橡皮鸭
            RubberDuck rubberDuck = new RubberDuck();
            rubberDuck.performFly();
            rubberDuck.performQuark();
            // 诱饵鸭
            DecoyDuck decoyDuck = new DecoyDuck();
            decoyDuck.performFly();
            decoyDuck.performQuark();
        }
    }
    
  • 相关阅读:
    Python网络编程 —— 粘包问题及解决方法
    Python网络编程 —— socket(套接字)及通信
    Python网络编程 —— 网络基础知识
    Python
    MySQL 之 数据的导出与导入
    MySQL 之 慢查询优化及慢日志管理
    MySQL 之 索引进阶
    MySQL 之 索引
    MySQL 之 事务
    MySQL 之 表的存储引擎
  • 原文地址:https://www.cnblogs.com/jingqueyimu/p/12976506.html
Copyright © 2011-2022 走看看