初步理解设计模式——策略模式

468 阅读4分钟

一、概念与介绍

定义

通过定义一系列封装好的算法,使得它们能以不同的实现去完成相同的工作,相互之间可以进行替换。 策略模式属于行为型模式,它通过对算法进行封装,委派给不同的对象来对这些算法进行管理,将算法的责任和实现进行了分割。

应用场景

在实践中发现,策略模式不止可以用来封装算法,还可以封装几乎任何类型的规则。只要是需要在不同情况下应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。

应用举例

1.存储目标数据,到底是用数组,还是用链表。又或者,使用二叉树...

2.早餐是吃榨菜包、吃蒸饺,还是吃红糖馒头。

主要优点

1.当不同的行为堆砌在一个类中时,经常需要使用条件语句来选择合适的行为,将这些行为封装在一个个独立的Strategy类中,就可以在使用这些行为的类中消除条件语句(扩展性、可维护性好,可以减少判断语句的使用)。

2.策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码

3.策略模式把算法的使用放到Context环境类中,而算法的实现移到具体策略类中,实现了二者的分离。

主要缺点

1.策略类会很多,且所有的策略类都需要对外暴露。

2.客户端必须理解所有策略算法的区别,以便选择恰当的算法类。

二、结构与实现

模式的结构

策略模式.png

模式的实现

//抽象策略类
interface Strategy {
    public void strategyMethod();    //策略方法
}
//具体策略类A
class ConcreteStrategyA implements Strategy {
    public void strategyMethod() {
        System.out.println("执行策略A:从蒸笼里拿一份蒸饺");
    }
}
//具体策略类B
class ConcreteStrategyB implements Strategy {
    public void strategyMethod() {
        System.out.println("执行策略B:从蒸笼里拿一个红糖馒头");
    }
}
//环境类
class Context {
    private Strategy strategy;

    public void startStrategy(Strategy strategy) {
        this.strategy = strategy;
        strategy.strategyMethod();
    }
}
//策略模式
public class StrategyPattern {
    public static void main(String[] args) {
        Context c = new Context();
        //执行策略A
        Strategy strategyA = new ConcreteStrategyA();
        c.startStrategy(strategyA);
        System.out.println("-----------------");
        //执行策略B
        Strategy strategyB = new ConcreteStrategyB();
        c.startStrategy(strategyB);
    }
}

程序运行结果

执行策略A:从蒸笼里拿一份蒸饺
-----------------
执行策略B:从蒸笼里拿一个红糖馒头

这里的环境类Context可以理解为早餐店,但是我们(客户端)却要自己从蒸笼里找到对应的食物。感觉有点不对劲啊。

三、策略工厂模式(拓展)

前面说过,策略模式的缺点之一就是“客户端必须理解所有策略算法的区别,以便选择恰当的算法类”。当算法类越来越多,客户端的工作就愈加困难了...

那么,能不能把这些判断的过程从客户端转移到其他地方呢?这时就要考虑到我们的环境类Context了。我们可以将Context类改造成简单工厂。这样,客户端不必选择好策略传递给Context,只需要传递表示当前情况的字段,让Context类根据获取到的不同情况,选择合适的策略。

在这个例子里,我们可以理解为:在早餐店,客户只需要喊一声:我要吃...,老板会帮你拿的。

话不多说,让我们将前面的代码稍作调整。

首先是环境类Context:

//环境类
class Context {

    public static final String  DUMPLINGS = "蒸饺";
    public static final String STEAMED_BUN = "红糖馒头";
    private Strategy strategy;

    public void startStrategy(String type) {
        System.out.println("客官稍等,我马上拿给您");
        switch (type) {
            //执行策略A
            case DUMPLINGS:
                strategy = new ConcreteStrategyA();
                break;
            //执行策略B
            case STEAMED_BUN:
                strategy = new ConcreteStrategyB();
                break;
            default:
                break;
        }
        strategy.strategyMethod();
    }
}

然后是客户端:

package Strategy;

import static Strategy.Context.DUMPLINGS;
import static Strategy.Context.STEAMED_BUN;

//策略工厂模式
public class StrategyPattern {
    public static void main(String[] args) {
        Context c = new Context();
        //想吃饺子
        System.out.println("我想吃"+ DUMPLINGS);
        c.startStrategy(DUMPLINGS);
        
        System.out.println("-----------------");
        
        //想吃红糖馒头
        System.out.println("我想吃"+ STEAMED_BUN);
        c.startStrategy(STEAMED_BUN);
    }
}

程序运行结果

我想吃蒸饺
客官稍等,我马上拿给您
执行策略A:从蒸笼里拿一份蒸饺
-----------------
我想吃红糖馒头
客官稍等,我马上拿给您
执行策略B:从蒸笼里拿一个红糖馒头

好了,关于策略模式的初步理解,就到这里了。本人也是刚接触设计模式,想分享下自己的理解与大家互相提高。文中若有不恰当的地方,有劳各位指出,多谢观看!