zoukankan      html  css  js  c++  java
  • 六、策略模式

    策略模式

    一、什么是策略模式

    策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。比如每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。

    策略模式(Strategy),定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换。

    UML结构图如下:

    png

    其中,Context是上下文,维护了一个对Strategy对象的引用;Strategy是策略类,用于定义所有支持算法的公共接口;ConcreteStrategy是具体策略类,封装了具体的算法或行为,继承于Strategy。

    1. Context上下文

    Context上下文角色,也叫Context封装角色,起承上启下的作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。

    public class Context {
        
        Strategy strategy;
        
        public Context(Strategy strategy) {
            this.strategy = strategy;
        }
        
        //上下文接口
        public void contextInterface() {
            strategy.algorithmInterface();
        }
    
    }
    

    2. 策略角色

    抽象策略角色,是对策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。algorithm是“运算法则”的意思。

    public abstract class Strategy {
        //算法方法
        public abstract void algorithmInterface();
    }
    

    3. 具体策略角色

    用于实现抽象策略中的操作,即实现具体的算法,下方用print代替。测试类共3个ConcreteStrategy,其它两个类与ConcreteStrategyA同理,就不再赘述了。

    public class ConcreteStrategyA extends Strategy {
    
        @Override
        public void algorithmInterface() {
            System.out.println("算法A实现");
        }
    
    }
    

    4. Client客户端

    下面依次更换策略,测试一下策略模式。

    public class Client {
        
        public static void main(String[] args) {
            Context context;
            
            context = new Context(new ConcreteStrategyA());
            context.contextInterface();
            
            context = new Context(new ConcreteStrategyB());
            context.contextInterface();
            
            context = new Context(new ConcreteStrategyC());
            context.contextInterface();
        }
    }
    
    /**测试结果
    算法A实现
    算法B实现
    算法C实现
    */
    

    二、策略模式的应用及优缺点

    应用场景

    • 多个类只有算法或行为上稍有不同的场景
    • 算法需要自由切换的场景
    • 需要屏蔽算法规则的场景

    优点:

    1. 算法可以自由切换
    2. 避免使用多重条件判断(如果不用策略模式我们可能会使用多重条件语句,不利于维护)
    3. 扩展性良好,增加一个策略只需实现接口即可

    缺点:

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

    三、策略模式案例

    我们来模拟一个下班回家的场景,需要自己选择不同的交通工具来回家

    1、上下文类

    首先声明一个TravelContext对象,通过构造方法,传入具体的交通工具。

    public class TravelContext {
        private Vehicle vehicle;
    
        public TravelContext(Vehicle vehicle){
            this.vehicle = vehicle;
        }
    
        public void goHome(){
            if (vehicle!=null){
                vehicle.travel();
            }
        }
    }
    

    2、交通工具抽象类

    public interface Vehicle {
        void travel();
    }
    

    3、不同的交通工具类

    public class Bus implements Vehicle {
        public void travel() {
            System.out.println("乘坐巴士");
        }
    }
    
    public class Car implements Vehicle {
        public void travel() {
            System.out.println("乘坐小汽车");
        }
    }
    
    public class Taxi implements Vehicle {
        public void travel() {
            System.out.println("乘坐出租车");
        }
    }
    

    4、Client客户端

    下面写一个简单的程序测试一下上方编写的代码。

    public class Client {
        public static void main(String[] args) {
            TravelContext travelContext = null;
            System.out.println("请选择回家乘坐的交通工具:1.小汽车 2.出租车 3.巴士");
            Scanner scanner = new Scanner(System.in);
            int input = scanner.nextInt();
            switch (input){
                case 1:
                    travelContext = new TravelContext(new Car());
                    travelContext.goHome();
                    break;
                case 2:
                    travelContext = new TravelContext(new Taxi());
                    travelContext.goHome();
                    break;
                case 3:
                    travelContext = new TravelContext(new Bus());
                    travelContext.goHome();
                    break;
                default:
                    System.out.println("请输入1/2/3");
                    break;
            }
        }
    }
    
    /**测试结果
    请选择回家乘坐的交通工具:1.小汽车 2.出租车 3.巴士
    3
    乘坐巴士
    */
    
  • 相关阅读:
    NYOJ 625 笨蛋的难题(二)
    NYOJ 102 次方求模
    ZJU Least Common Multiple
    ZJUOJ 1073 Round and Round We Go
    NYOJ 709 异形卵
    HDU 1279 验证角谷猜想
    BNUOJ 1015 信息战(一)——加密程序
    HDU 1202 The calculation of GPA
    "蓝桥杯“基础练习:字母图形
    "蓝桥杯“基础练习:数列特征
  • 原文地址:https://www.cnblogs.com/lee0527/p/11892231.html
Copyright © 2011-2022 走看看