设计模式之策略模式

作者: WilliamIT | 来源:发表于2018-02-02 22:35 被阅读23次
策略.jpg

策略模式

1、什么是策略模式

    策略模式让算法独立于使用它的客户而独立变化。策略模式重点是封装不同的算法和行为,不同的场景下可以相互替换。策略模式是开闭原则的体现,开闭原则讲的是一个软件实体应该对扩展开放对修改关闭。策略模式在新的策略增加时,不会影响其他类的修改,增加了扩展性,也就是对扩展是开放的;对于场景来说,只依赖于抽象,而不依赖于具体实现,所以对修改是关闭的。策略模式的认识可以借助《java与模式》一书中写到诸葛亮的锦囊妙计来学习,在不同的场景下赵云打开不同的锦囊,便化险为夷,锦囊便是抽象策略,具体的锦囊里面的计策便是具体的策略角色,场景就是赵云,变化的处境选择具体策略的条件。策略模式可以有效的避免过多的if-else的出现。

2、策略模式的特性

下面通过一个策略模式的UML图表示:
[图片上传失败...(image-236cbe-1517582099931)]图2-1 策略模式UML图

  • 抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
  • 具体策略角色:包装了相关的算法和行为。
  • 环境角色:持有一个策略类的引用,最终给客户端调用。

3、举例说明

    根据现在广大人民都喜欢vip来举例子吧。

  • 一级vip 9折
  • 二级vip 8折
  • 三级vip 7折

常规的方法来展示:

public class VIP {
    enum VipType {
        one,two,three
    }
    double getMoney(double money,VipType type){
        switch (type){
            case one:
                return money*0.9;
            case two:
                return money*0.8;
            case three:
                return money*0.7;
        }
        return money;
    }
}

    创建一个计算钱的类,根据输入的参数,使用switch来完成。

例子:

VIP vip=new VIP();
System.out.println(vip.getMoney(1000, VIP.VipType.one));
System.out.println(vip.getMoney(1000, VIP.VipType.two));
System.out.println(vip.getMoney(1000, VIP.VipType.three));

总结:
看起来好像很简单的样子,但是如果有很多很多种vip,VIP类会变得非常庞大;如果计算方式改变呢,每次都需要修改这个类,维护起来会非常费劲。

接下来展现我们的方法了:

1、 定义算法接口(抽象策略角色)

public class OneStrategy implements Strategy {
    @Override
    public double getMoney(double monty, VIP.VipType type) {
        return monty*0.9;
    }
}
public class TwoStrategy implements Strategy {
    @Override
    public double getMoney(double monty, VIP.VipType type) {
        return monty*0.8;
    }
}
public class ThreeStrategy implements Strategy {
    @Override
    public double getMoney(double monty, VIP.VipType type) {
        return monty*0.7;
    }
}

3、 定义上下文(环境角色)
    首先定义一个工厂:

import java.util.HashMap;
import java.util.Map;

public class StrategyFactory {
    private static StrategyFactory factory;

    private StrategyFactory() {
    }

    private static Map<VIP.VipType, Strategy> map = new HashMap<>();

    static {
        map.put(VIP.VipType.one, new OneStrategy());
        map.put(VIP.VipType.two, new TwoStrategy());
        map.put(VIP.VipType.three, new ThreeStrategy());
    }

    public static StrategyFactory getInstance() {
        if (factory == null) {
            synchronized (StrategyFactory.class) {
                if (factory == null) {
                    factory = new StrategyFactory();
                }
            }
        }
        return factory;
    }

    public Strategy getStrategy(VIP.VipType vipType) {
        return map.get(vipType);
    }
}

    用来生产不同的具体决策对象。

    接下来定义上下文:

public class Context {
    private Strategy strategy;//策略父类

    double getMoney(double money, VIP.VipType vipType){
       strategy= StrategyFactory.getInstance().getStrategy(vipType);//获得具体策略
       return strategy.getMoney(money,vipType);
    }

    public Strategy getStrategy() {
        return strategy;
    }

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }
}

实例:

Context context = new Context();
System.out.println(context.getMoney(1000, VIP.VipType.one));
System.out.println(context.getMoney(1000, VIP.VipType.two));
System.out.println(context.getMoney(1000, VIP.VipType.three));

总结:
    策略模式把具体的算法封装到了具体策略角色内部,增强了可扩展性,隐蔽了实现细节;它替代继承来实现,避免了if- else这种不易维护的条件语句。当然我们也可以看到,策略模式由于独立策略实现,使得系统内增加了很多策略类;对客户端来说必须知道兜友哪些具体策略, 而且需要知道选择具体策略的条件。

4、优缺点

 优点:
    1、 抽象性更好,重用一下算法和行为。
    2、 提供了可以替换继承关系的办法,算法封装在独立的Strategy中,可以更好的理解和扩展。
    3、 消除了一些if else条件语句。
    4、 可以提供相同行为的不同实现。
 缺点:
    1、 客户端必须知道所有的策略类,并自行决定使用哪一个策略类
    2、 Strategy和Context之间的通信开销 :无论各个Strategy实现的算法是简单还是复杂, 它们都共享Strategy定义的接口。
    3、 策略模式将造成产生很多策略类:可以通过使用享元模式在一定程度上减少对象的数量。

您的批评是我最好的收获!!!
如果可以请加我的微信公众号一起学习,刚起步希望共同努力!


微信公众号二维码.jpg

相关文章

  • PHP设计模式之策略模式

    PHP设计模式之策略模式

  • PHP设计模式之策略模式

    PHP设计模式之策略模式

  • 简说设计模式之策略模式

    前言:对于设计模式基础概念可以去看[简说设计模式之设计模式概述] 一、什么是策略模式 策略(Strategy)模式...

  • 策略模式

    参考资料:漫话:如何给女朋友解释什么是策略模式? 设计模式之策略模式(实例+Demo) Java设计模式(8)——...

  • 学习Head First设计模式Day1

    Java设计模式之设计模式 策略模式:策略模式定义了算法簇,分别封装起来,让他们之间可以互相替换,此设计模式让算法...

  • 策略模式 2018-11-04

    设计模式之策略模式 官方说明设计模式的3个角色: 环境角色:context , 持有一个策略的引用 抽象策略角色,...

  • Java设计模式——策略模式

    Java设计模式之策略模式 这期分享的模式是策略模式是程序设计中最常用的了,因为开发工作中总是会使用到策略模式。 ...

  • 策略模式

    本文参考自: 《JAVA设计模式》之策略模式(Strategy) 1. 作用 策略模式属于对象的行为模式。其用意是...

  • 设计模式(Swift) - 单例模式、备忘录模式和策略模式

    设计模式(Swift) - 单例模式、备忘录模式和策略模式 设计模式(Swift) - 单例模式、备忘录模式和策略模式

  • 设计模式之策略模式总结

    再上一篇文章《设计模式之策略模式》中,我们通过模拟鸭子项目,了解了什么是策略模式,怎么使用策略模式。本文将通过鸭子...

网友评论

    本文标题:设计模式之策略模式

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