【设计模式】 策略模式(Strategy Pattern)- 最易懂的设计模式解析

来源:互联网 发布:linux中telnet命令 编辑:程序博客网 时间:2024/05/17 04:44

前言

今天我来全面总结一下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. 将算法的责任和本身进行解耦 
    对算法进行封装,将算法的责任和算法本身分割开,委派给不同的对象管理。
  3. 让算法和对象分开来,使得算法可以独立于使用它的客户而变化

2. 模式原理

2.1 UML类图 & 组成

UML类图

2.2 实例讲解

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

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

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

public abstract class Strategy {      public abstract void Show();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

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

//为春节准备的促销活动Aclass StrategyA extends Strategy{    @Override    public void show() {        System.out.println("为春节准备的促销活动A");    }}//为中秋节准备的促销活动Bclass StrategyB extends Strategy{    @Override    public void show() {        System.out.println("为中秋节准备的促销活动B");    }}//为圣诞节准备的促销活动Cclass StrategyC extends Strategy{    @Override    public void show() {        System.out.println("为圣诞节准备的促销活动C");    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

步骤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();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

步骤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();    }   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

结果输出

对于春节:为春节准备的促销活动A对于中秋节:为中秋节准备的促销活动B对于圣诞节:为圣诞节准备的促销活动B
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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


3. 优缺点

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

3.1 优点

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

3.2 缺点

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

4. 应用场景

  • 一个系统需要动态地在几种算法中选择一种的情况
  • 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为
  • 如果一个对象有很多的行为,如果不使用合适的模式,这些行为就只好使用多重的if-else语句来实现,此时,可以使用策略模式,把这些行为转移到相应的具体策略类里面,就可以避免使用难以维护的多重条件选择语句,并体现面向对象涉及的概念。
  • 不希望客户端知道复杂的、与算法相关的数据结构,在具体策略类中封装算法和相关的数据结构,提高算法的保密性与安全性。 


0 0
原创粉丝点击