zoukankan      html  css  js  c++  java
  • 设计模式-策略模式

    定义:

        策略模式是对算法的包装,把使用算法的责任和算法本身分隔开,委派给不同的对象管理。策略模式通常把一系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。

    优点   

    • 算法可以自由切换

    • 避免使用多重条件判断(如果不用策略模式我们可能会使用多重条件语句,不利于维护)

    • 扩展性良好,增加一个策略只需实现接口即可

    • 提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。

    缺点:

    • 策略类数量会增多,每个策略都是一个类,复用的可能性很小

    • 所有的策略类都需要对外暴露

    • 只适合偏平的算法结构

    角色:

    1. 抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。

    2. 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。

    3. 环境(Context)类:持有一个策略类的引用,最终给客户端调用。

    结构说明:

    策略模式的结构图

    具体实现:

    1、策略接口

    //策略接口
    public interface IStrategy {
        //定义的抽象算法方法 来约束具体的算法实现方法
        public void algorithmMethod();
    } 

    2、具体策略实现 

    // 具体的策略实现1
    public class ConcreteStrategy1 implements IStrategy {
        //具体的算法实现
        @Override
        public void algorithmMethod() {
            System.out.println("this is ConcreteStrategy method...");
        }
    }
    ​
    // 具体的策略实现
    public class ConcreteStrategy2 implements IStrategy {
        //具体的算法实现
        @Override
        public void algorithmMethod() {
            System.out.println("this is ConcreteStrategy method...");
        }
    } 

    3、策略上下文 

    /**
     * 策略上下文
     */
    public class StrategyContext {
        //持有一个策略实现的引用
        private IStrategy strategy;
        //使用构造器注入具体的策略类
        public StrategyContext(IStrategy strategy) {
            this.strategy = strategy;
        }
    ​
        public void contextMethod(){
            //调用策略实现的方法
            strategy.algorithmMethod();
        }
    } 

    3、调用策略 

    //1.创建具体测策略实现
    IStrategy strategy = new ConcreteStrategy2();
    //2.在创建策略上下文的同时,将具体的策略实现对象注入到策略上下文当中
    StrategyContext ctx = new StrategyContext(strategy);
    //3.调用上下文对象的方法来完成对具体策略实现的回调
    ctx.contextMethod(); 

    使用场景

    • 多个类只有算法或行为上稍有不同的场景

    • 算法需要自由切换的场景

    • 需要屏蔽算法规则的场景

    spring应用场景:

    1、借助Spring 强大的依赖注入,消除if/else的关键代码,Spring 会自动将 EntStrategy 接口的实现类注入到这个Map中。前提是你这个实现类得是交给Spring 容器管理的。 

    @Component
    public class EntStrategyHolder {
    ​
        // 关键功能 Spring 会自动将 IStrategy 接口的类注入到这个Map中
        @Autowired
        private Map<String, IStrategy> entStrategyMap;
    ​
        public IStrategy getBy(String entNum) {
            return entStrategyMap.get(entNum);
        }
    } 

    具体实现原理

    @Component
    public class StrategyResolver implements InitializingBean, ApplicationContextAware {
    ​
        private ApplicationContext applicationContext;
        private Map<String, Sign> StrategyHandlerMap = new HashMap<>();
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }
        @Override
        public void afterPropertiesSet() {
            Map<String, Sign> beanMap = applicationContext.getBeansOfType(Strategy.class);
            for (String key : beanMap.keySet()) {
                this.StrategyHandlerMap.put(beanMap.get(key).companyCode(), beanMap.get(key));
            }
        }
        public Strategy getHandler(String companyCode) {
            return StrategyHandlerMap.get(companyCode);
        }
  • 相关阅读:
    倒立摆
    Mybatis在oracle、mysql、db2、sql server的like模糊查询
    BUG系列:转让startActivityForResult()&amp;onActivityResult()没有反应
    建立地方Jekyll周边环境
    HDU 1535 Invitation Cards (POJ 1511)
    STM8S---IO复用配置(STVP方式)
    【菜鸟看框架】——EF怎样自己主动生成实体
    Keywords Search (ac 自己主动机)
    liGDX life_cycle (生命周期)
    html浏览器兼容性的 JavaScript语法
  • 原文地址:https://www.cnblogs.com/yuarvin/p/13040477.html
Copyright © 2011-2022 走看看