美文网首页知识 | 解析程序员的核心能力android share
策略模式(Strategy Pattern)- 最易懂的设计模式

策略模式(Strategy Pattern)- 最易懂的设计模式

作者: Carson带你学安卓 | 来源:发表于2016-08-23 16:04 被阅读3778次

    前言

    今天我来全面总结一下Android开发中最常用的设计模式 -策略模式。

    其他设计模式介绍
    1分钟全面了解“设计模式”
    单例模式(Singleton) - 最易懂的设计模式解析
    简单工厂模式(SimpleFactoryPattern)- 最易懂的设计模式解析
    工厂方法模式(Factory Method)- 最易懂的设计模式解析
    抽象工厂模式(Abstract Factory)- 最易懂的设计模式解析
    策略模式(Strategy Pattern)- 最易懂的设计模式解析
    适配器模式(Adapter Pattern)- 最易懂的设计模式解析
    代理模式(Proxy Pattern)- 最易懂的设计模式解析
    模板方法模式(Template Method) - 最易懂的设计模式解析
    建造者模式(Builder Pattern)- 最易懂的设计模式解析
    外观模式(Facade Pattern) - 最易懂的设计模式解析


    目录

    策略模式.jpg

    1. 介绍

    1.1 定义

    定义一系列算法,将每个算法封装到具有公共接口的一系列策略类中,从而使它们可以相互替换 & 让算法可在不影响客户端的情况下发生变化

    简单来说:准备一组算法 & 将每一个算法封装起来,让外部按需调用 & 使得互换

    1.2 作用(解决的问题)

    将算法的责任和本身进行解耦,使得:

    1. 算法可独立于使用外部而变化
    2. 客户端方便根据外部条件选择不同策略来解决不同问题

    策略模式仅仅封装算法(包括添加 & 删除),但策略模式并不决定在何时使用何种算法,算法的选择由客户端来决定


    2. 模式原理

    2.1 UML类图 & 组成

    UML类图

    2.2 实例讲解

    接下来我用一个实例来对策略模式进行更深一步的介绍。
    a. 实例概况

    • 背景:小成有一家百货公司,最近在定年度的促销活动
    • 冲突:每个节日用同一个促销活动太枯燥,没吸引力
    • 解决方案:针对不同节目使用不同促销活动进行促销

    b. 使用步骤
    步骤1: 定义抽象策略角色(Strategy):百货公司所有促销活动的共同接口

    
    public abstract class Strategy {  
    
        public abstract void Show();
    }
    

    步骤2:定义具体策略角色(Concrete Strategy):每个节日具体的促销活动

    //为春节准备的促销活动A
    class StrategyA extends Strategy{
    
        @Override
        public void show() {
            System.out.println("为春节准备的促销活动A");
        }
    }
    
    //为中秋节准备的促销活动B
    class StrategyB extends Strategy{
    
        @Override
        public void show() {
            System.out.println("为中秋节准备的促销活动B");
        }
    }
    
    //为圣诞节准备的促销活动C
    class StrategyC extends Strategy{
    
        @Override
        public void show() {
            System.out.println("为圣诞节准备的促销活动C");
        }
    }
    

    步骤3:定义环境角色(Context):用于连接上下文,即把促销活动推销给客户,这里可以理解为销售员

    class Context_SalesMan{
    //持有抽象策略角色的引用
        private Strategy strategy;
    
        //生成销售员实例时告诉销售员什么节日(构造方法)
        //使得让销售员根据传入的参数(节日)选择促销活动(这里使用一个简单的工厂模式)
        public SalesMan(String festival) {
            switch ( festival) {
                //春节就使用春节促销活动
                case "A":
                    strategy = new StrategyA();
                    break;
                //中秋节就使用中秋节促销活动
                case "B":
                    strategy = new StrategyB();
                    break;
                //圣诞节就使用圣诞节促销活动
                case "C":
                    strategy = new StrategyC();
                    break;
            }
    
        }
    
        //向客户展示促销活动
        public void SalesManShow(){
            strategy.show();
        }
    
    }
    

    步骤4:客户端调用-让销售员进行促销活动的落地

    
    public class StrategyPattern{
      public static void main(String[] args){
    
            Context_SalesMan mSalesMan ;
    
            //春节来了,使用春节促销活动
            System.out.println("对于春节:");
            mSalesMan =  Context_SalesMan SalesMan("A");
            mSalesMan.SalesManShow();
            
            
            //中秋节来了,使用中秋节促销活动
            System.out.println("对于中秋节:");
            mSalesMan =  Context_SalesMan SalesMan("B");
            mSalesMan.SalesManShow();
    
            //圣诞节来了,使用圣诞节促销活动
            System.out.println("对于圣诞节:");
            mSalesMan =  Context_SalesMan SalesMan("C");
            mSalesMan.SalesManShow();  
      }   
    }
       
    

    结果输出

    对于春节:
    为春节准备的促销活动A
    对于中秋节:
    为中秋节准备的促销活动B
    对于圣诞节:
    为圣诞节准备的促销活动B
    

    通过上述这个常见的生活例子,我相信你已经完全明白了策略模式的原理了!!


    3. 优缺点

    在全面解析完后,我来分析下其优缺点:

    3.1 优点

    • 策略类之间可以自由切换
      由于策略类都实现同一个接口,所以使它们之间可以自由切换。
    • 易于扩展
      增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码,符合“开闭原则“
    • 避免使用多重条件选择语句(if else),充分体现面向对象设计思想。

    3.2 缺点

    • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
    • 策略模式将造成产生很多策略类,可以通过使用享元模式在一定程度上减少对象的数量。

    4. 应用场景

    动态选择多种复杂行为

    该行为可理解为:

    1. 复杂的算法 / 数据结构
    2. 类的行为 / 方法
      注:提高了行为的保密 & 阿暖

    5. 总结

    本文主要对策略模式进行了全面介绍,接下来将介绍其他设计模式,有兴趣可以继续关注Carson_Ho的安卓开发笔记!!!!


    请点赞!因为你的鼓励是我写作的最大动力!

    相关文章阅读
    单例模式(Singleton) - 最易懂的设计模式解析
    简单工厂模式(SimpleFactoryPattern)- 最易懂的设计模式解析
    工厂方法模式(Factory Method)- 最易懂的设计模式解析
    抽象工厂模式(Abstract Factory)- 最易懂的设计模式解析
    策略模式(Strategy Pattern)- 最易懂的设计模式解析
    适配器模式(Adapter Pattern)- 最易懂的设计模式解析
    代理模式(Proxy Pattern)- 最易懂的设计模式解析
    模板方法模式(Template Method) - 最易懂的设计模式解析
    建造者模式(Builder Pattern)- 最易懂的设计模式解析
    外观模式(Facade Pattern) - 最易懂的设计模式解析


    欢迎关注Carson_Ho的简书!

    不定期分享关于安卓开发的干货,追求短、平、快,但却不缺深度

    相关文章

      网友评论

      • 96699d8a7c6a:不加任何“简单工厂模式”的纯策略模式的客户端用该如下
        ===================================
        public static void main(String[] args){

        // 选择并创建需要使用的策略对象
        // 例如现在要做春节的活动
        Strategy strategy = new StrategyA();

        // 创建环境
        Context context = new Context(strategy);

        // 具体的活动
        context.contextInterface();
        }
        ===================================

        而Context应该如下
        ===================================
        //持有一个具体策略的对象
        private Strategy strategy;

        /**
        * 构造函数,传入一个具体策略对象
        *
        * @param strategy 具体策略对象
        */
        public Context(Strategy strategy) {
        this.strategy = strategy;
        }

        /**
        * 策略方法
        */
        public void contextInterface() {

        strategy.show();
        }
        ===================================
        应该是这样的:smile:
      • 23cb804e29bf:我看不明白,客户端需要知道使用哪种策略的话,为什么不省去中间代码,直接
        new StrategyA().show();
        new StrategyB().show();
        是我理解能力太低,还是没遇到麻烦的场景,一直都没觉得有必要用这个模式
      • 牧头码尾:表示Context_SalesMan类中的构造方法SalesMan(String festival)看不懂,既然是构造方法,为什么名字和Context_SalesMan不一样,还有后面的使用mSalesMan = Context_SalesMan SalesMan("A");也有点不知所云,既然是构造方法,应该是new出来啊。有没有解释下
        96699d8a7c6a:不加任何“简单工厂模式”的纯策略模式的客户端应该如下
        ===================================
        public static void main(String[] args){

        // 选择并创建需要使用的策略对象
        // 例如现在要做春节的活动
        Strategy strategy = new StrategyA();

        // 创建环境
        Context context = new Context(strategy);

        // 具体的活动
        context.contextInterface();
        }
        ===================================

        而Context应该如下
        ===================================
        //持有一个具体策略的对象
        private Strategy strategy;

        /**
        * 构造函数,传入一个具体策略对象
        *
        * @param strategy 具体策略对象
        */
        public Context(Strategy strategy) {
        this.strategy = strategy;
        }

        /**
        * 策略方法
        */
        public void contextInterface() {

        strategy.show();
        }
        ===================================
        b0f758808ba4:SalesMan 只是一个实例方法,这应该不是 Java 代码,或者是伪代码
      • AJiangNo1:之所以大家说策略模式跟简单工厂很像,傻傻分不清楚,其实博主这个策略模式举得例子并不是单纯的策略模式,这是策略+简单工厂优化后的模式,本来策略模式应该类似如下:class Context_SalesMan{
        private Strategy strategy;
        public SalesMan(Strategy strategy) {
        this.strategy=strategy;
        }
        }
        //向客户展示促销活动
        public void SalesManShow(){
        strategy.show();
        }
        }
        具体的实现过程需要在客户端完成,所以显得很low,故而一般都优化成策略+简单工厂模式,如博主所写的那样。(如见解有误,欢迎指正)
        23cb804e29bf:客户端需要知道使用哪种策略的话,为什么不省去中间代码,直接
        new StrategyA().show();
        new StrategyB().show();
        没看明白中间类Context_SalesMan存在的意义
      • 666swb:这是简单工厂:scream:
      • 四大爷:这个策略模式,怎么感觉跟工厂模式很像啊,只是业务场景有区别
        星林的窗:我看起来也跟简单工厂模式很像:smile:

      本文标题:策略模式(Strategy Pattern)- 最易懂的设计模式

      本文链接:https://www.haomeiwen.com/subject/vqqnsttx.html