GVKun编程网logo

JAVA 中的设计模式三(策略模式)(java设计模式之策略模式)

1

最近很多小伙伴都在问JAVA中的设计模式三和策略模式这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展23种设计模式(12):策略模式、C++设计模式:策略模式、Fun论设计模式之6

最近很多小伙伴都在问JAVA 中的设计模式三策略模式这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展23 种设计模式(12):策略模式、C++设计模式:策略模式、Fun 论设计模式之 6:策略模式(Strategy Pattern)与 Java 8 的 Function 类接口、java - 策略模式、状态模式、卫语句,避免多重if-else(转)等相关知识,下面开始了哦!

本文目录一览:

JAVA 中的设计模式三(策略模式)(java设计模式之策略模式)

JAVA 中的设计模式三(策略模式)(java设计模式之策略模式)

问题:
如何让算法和对象分开来,使得算法可以独立于使用它的客户而变化?
 
方案:
把一个类中经常改变或者将来可能改变的部分提取出来,作为一个接口,然后在类中包含这个对象的实例,这样类的实例在运行时就可以随意调用实现了这个接口的类的行为。比如定义一系列的算法,把每一个算法封装起来,并且使它们可相互替换,使得算法可独立于使用它的客户而变化。这就是策略模式。
 
 
适用情况:
许多相关的类仅仅是行为有异。 “策略” 提供了一种用多个行为中的一个行为来配置一个类的方法。即一个系统需要动态地在几种算法中选择一种当一个应用程序需要实现一种特定的服务或者功能,而且该程序有多种实现方式时使用。一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的 Strategy 类中以代替这些条件语句
 
优点:
1、可以动态的改变对象的行为
缺点:
1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类
2、策略模式将造成产生很多策略类
 
 应用:
我们平时出行的方式:出行方式有很多种,具体用哪一种根据动态的选择;
 
 首先创建我们的抽象行为类,和具体的行为类;
 1 package strategy;//策略模式
 2 
 3 //抽象的行为类
 4 public interface Strategy {
 5     public void go();//出行方式
 6 }
 7 
 8 
 9 
10 
11 package strategy;
12 
13 public class ConcreteStrategy1 implements Strategy {//具体的出行方式
14 
15     @Override
16     public void go() {
17         // TODO Auto-generated method stub
18         System.out.println("坐公交车!");
19     }
20 
21 }
22 
23 
24 
25 
26 
27 package strategy;
28 
29 public class ConcreteStrategy2 implements Strategy {//具体的出行方式
30 
31     @Override
32     public void go() {
33         // TODO Auto-generated method stub
34         System.out.println("自驾车!");
35     }
36 }

 然后创建一个调用者,也就是使用者,把能使用的行为给导入进来;

 1 package strategy;
 2 
 3 public class Context {//环境类其实也就是一个调用类,出行的人
 4     private Strategy s;
 5 
 6     public Context(Strategy s) {
 7         super();
 8         this.s = s;
 9     }
10     public void operate(){
11         s.go();
12     }
13 }

 最后就是进行出行了;

 1 package strategy;
 2 
 3 public class Test {
 4     public static void main(String[] args) {
 5         Context c =new Context(new ConcreteStrategy1());
 6         c.operate();
 7         
 8         c =new Context(new ConcreteStrategy2());
 9         c.operate();
10     }
11 }

 

 

 

 
 
 
 
 

23 种设计模式(12):策略模式

23 种设计模式(12):策略模式

定义:定义一组算法,将每个算法都封装起来,并且使他们之间可以互换。

类型:行为类模式

类图:

       策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这些类实现相同的接口,相互之间可以替换。在前面说过的行为类模式中,有一种模式也是关注对算法的封装 —— 模版方法模式,对照类图可以看到,策略模式与模版方法模式的区别仅仅是多了一个单独的封装类 Context,它与模版方法模式的区别在于:在模版方法模式中,调用算法的主体在抽象的父类中,而在策略模式中,调用算法的主体则是封装到了封装类 Context 中,抽象策略 Strategy 一般是一个接口,目的只是为了定义规范,里面一般不包含逻辑。其实,这只是通用实现,而在实际编程中,因为各个具体策略实现类之间难免存在一些相同的逻辑,为了避免重复的代码,我们常常使用抽象类来担任 Strategy 的角色,在里面封装公共的代码,因此,在很多应用的场景中,在策略模式中一般会看到模版方法模式的影子。

 

策略模式的结构

  • 封装类:也叫上下文,对策略进行二次封装,目的是避免高层模块对策略的直接调用。
  • 抽象策略:通常情况下为一个接口,当各个实现类中存在着重复的逻辑时,则使用抽象类来封装这部分公共的代码,此时,策略模式看上去更像是模版方法模式。
  • 具体策略:具体策略角色通常由一组封装了算法的类来担任,这些类之间可以根据需要自由替换。

策略模式代码实现

interface IStrategy {
	public void doSomething();
}
class ConcreteStrategy1 implements IStrategy {
	public void doSomething() {
		System.out.println("具体策略1");
	}
}
class ConcreteStrategy2 implements IStrategy {
	public void doSomething() {
		System.out.println("具体策略2");
	}
}
class Context {
	private IStrategy strategy;
	
	public Context(IStrategy strategy){
		this.strategy = strategy;
	}
	
	public void execute(){
		strategy.doSomething();
	}
}

public class Client {
	public static void main(String[] args){
		Context context;
		System.out.println("-----执行策略1-----");
		context = new Context(new ConcreteStrategy1());
		context.execute();

		System.out.println("-----执行策略2-----");
		context = new Context(new ConcreteStrategy2());
		context.execute();
	}
}

 

策略模式的优缺点

       策略模式的主要优点有:

  • 策略类之间可以自由切换,由于策略类实现自同一个抽象,所以他们之间可以自由切换。
  • 易于扩展,增加一个新的策略对策略模式来说非常容易,基本上可以在不改变原有代码的基础上进行扩展。
  • 避免使用多重条件,如果不使用策略模式,对于所有的算法,必须使用条件语句进行连接,通过条件判断来决定使用哪一种算法,在上一篇文章中我们已经提到,使用多重条件判断是非常不容易维护的。

       策略模式的缺点主要有两个:

  • 维护各个策略类会给开发带来额外开销,可能大家在这方面都有经验:一般来说,策略类的数量超过 5 个,就比较令人头疼了。
  • 必须对客户端(调用者)暴露所有的策略类,因为使用哪种策略是由客户端来决定的,因此,客户端应该知道有什么策略,并且了解各种策略之间的区别,否则,后果很严重。例如,有一个排序算法的策略模式,提供了快速排序、冒泡排序、选择排序这三种算法,客户端在使用这些算法之前,是不是先要明白这三种算法的适用情况?再比如,客户端要使用一个容器,有链表实现的,也有数组实现的,客户端是不是也要明白链表和数组有什么区别?就这一点来说是有悖于迪米特法则的。

 

适用场景

        做面向对象设计的,对策略模式一定很熟悉,因为它实质上就是面向对象中的继承和多态,在看完策略模式的通用代码后,我想,即使之前从来没有听说过策略模式,在开发过程中也一定使用过它吧?至少在在以下两种情况下,大家可以考虑使用策略模式,

  • 几个类的主要逻辑相同,只在部分逻辑的算法和行为上稍有区别的情况。
  • 有几种相似的行为,或者说算法,客户端需要动态地决定使用哪一种,那么可以使用策略模式,将这些算法封装起来供客户端调用。

       策略模式是一种简单常用的模式,我们在进行开发的时候,会经常有意无意地使用它,一般来说,策略模式不会单独使用,跟模版方法模式、工厂模式等混合使用的情况比较多。

 

 

C++设计模式:策略模式

C++设计模式:策略模式

#pragma once
//strategy.h
/**
 * 策略模式(Strategy):它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化
 * 不会影响到使用算法的客户。
 * 
 * 面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象
 * 的抽象集合才是类。
*/

class Strategy
{
public:
    virtual double getResult(double data)=0;
    virtual ~Strategy();
};

class StrategyA:public Strategy
{
public:
    double getResult(double data);
};

class StrategyB:public Strategy
{
public:
    double getResult(double data);
};
//strategy.cpp
#include "strategy.h"
#include <iostream>

Strategy::~Strategy()
{
    std::cout<< "~Strategy() is called." << std::endl;
}

double StrategyA::getResult(double data)
{
    //std::cout<< "StrategyA::getResult(data) = " << data*1.0 << std::endl;

    return data*1.0;
}

double StrategyB::getResult(double data)
{
    //std::cout << "StrategyB::getResult(data) = " << data*2 << std::endl;

    return data*2.0;
}
#pragma once
//context.h
#include "strategy.h"
#include <memory>

class Context
{
private:
    //使用智能指针
    std::unique_ptr<Strategy> strategy=nullptr;
    //Strategy *strategy=nullptr;
public:
    Context(const char& schar);
    virtual ~Context();

    double getResult(double data);
};
//context.cpp

#include "context.h"
#include <iostream>

Context::Context(const char& schar)
{
    switch(schar)
    {
        case ''A'':
        case ''a'':
            strategy = std::move(std::unique_ptr<Strategy>(new StrategyA()));
            // strategy = new StrategyA();
            break;
        case ''B'':
        case ''b'':
            strategy = std::move(std::unique_ptr<Strategy>(new StrategyB()));
            // strategy = new StrategyB();
            break;
        default:
            break;
    }
}

double Context::getResult(double data)
{
    if(strategy)
    {
        return strategy->getResult(data);
    }

    return 0;
}

Context::~Context()
{
    std::cout << " -> ~Context()" << std::endl;
}
//main.cpp
#include "context.h"
#include <iostream>

/**
 * 客户端只需要知道Context类,不需要知道具体的策略.
 * windows下编译指令:
 *          g++ main.cpp context.cpp strategy.cpp -std=c++17 -o main.exe
 * 运行结果:
 *  - result of A: 100
 *  - result of B: 200
 *  -> ~Context()
 *  ~Strategy() is called.
 *  -> ~Context()
 * ~Strategy() is called.
 */

int main(int argc,char **argv)
{
    double input_data = 100.0;
    Context ca(''a'');
    Context cb(''B'');

    std::cout << " - result of A: " << ca.getResult(input_data) << std::endl;
    std::cout << " - result of B: " << cb.getResult(input_data) << std::endl;

    return 0;
}

 

Fun 论设计模式之 6:策略模式(Strategy Pattern)与 Java 8 的 Function 类接口

Fun 论设计模式之 6:策略模式(Strategy Pattern)与 Java 8 的 Function 类接口

  策略模式通常与使用标准模式的 Java 数据流(stream,Java 8 之后有)或者 Spark 的 RDD 数据流配合使用,用于改变数据的处理策略,一般用在 map 和 reduce 操作。

  意图:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。

  主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。

  何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。

  如何解决:将这些算法封装成一个一个的类,任意地替换。

  关键代码:实现同一个接口。

  应用实例: 1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。 2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。 3、JAVA AWT 中的 LayoutManager。 4、Spark 的 mapToPair。

  Java 内部和很多第三方工具的类库都用到了策略模式,因为很多类的用途需要自定策略。策略有两种指定方式:一种是在函数调用中传入函数式接口;一种是初始化策略类时传入 Function。

  首先咱们说说在函数调用中传入函数式接口的方式:

  Java 中的 Map,有两种函数会用到策略模式,比如:computeIfAbsent(不存在则按照策略添加)、computeIfPresent(存在则按照策略更新),需要传入 Function 类,或者 lambda 表达式,因为这两种需要根据键不同而制定不同策略(不要说为什么不直接传入值,可能需要延迟加载,或者使用同一策略创建键值)

  内部代码实现是这样的:

 1     @Override
 2     public V computeIfAbsent(final K k, final Function<? super K, ? extends V> function) {
 3         if (function == null) {
 4             throw new NullPointerException();
 5         }
 6         final int hash = hash(k);
 7         int n = 0;
 8         TreeNode<K, V> treeNode = null;
 9         Node<K, V> treeNode2 = null;
10         Node<K, V>[] array;
11         int n2;
12         if (this.size > this.threshold || (array = this.table) == null || (n2 = array.length) == 0) {
13             n2 = (array = this.resize()).length;
14         }
15         final int n3;
16         final Node<K, V> node;
17         if ((node = array[n3 = (n2 - 1 & hash)]) != null) {
18             Label_0169: {
19                 if (node instanceof TreeNode) {
20                     treeNode2 = (treeNode = (TreeNode<K, V>)node).getTreeNode(hash, k);
21                 }
22                 else {
23                     Node<K, V> next = node;
24                     K key;
25                     while (next.hash != hash || ((key = next.key) != k && (k == null || !k.equals(key)))) {
26                         ++n;
27                         if ((next = next.next) == null) {
28                             break Label_0169;
29                         }
30                     }
31                     treeNode2 = next;
32                 }
33             }
34             final V value;
35             if (treeNode2 != null && (value = treeNode2.value) != null) {
36                 this.afterNodeAccess(treeNode2);
37                 return value;
38             }
39         }
40         final V apply = (V)function.apply(k);
41         if (apply == null) {
42             return null;
43         }
44         if (treeNode2 != null) {
45             treeNode2.value = apply;
46             this.afterNodeAccess(treeNode2);
47             return apply;
48         }
49         if (treeNode != null) {
50             treeNode.putTreeVal(this, array, hash, k, apply);
51         }
52         else {
53             array[n3] = this.newNode(hash, k, apply, node);
54             if (n >= 7) {
55                 this.treeifyBin(array, hash);
56             }
57         }
58         ++this.modCount;
59         ++this.size;
60         this.afterNodeInsertion(true);
61         return apply;
62     }
63     
64     @Override
65     public V computeIfPresent(final K k, final BiFunction<? super K, ? super V, ? extends V> biFunction) {
66         if (biFunction == null) {
67             throw new NullPointerException();
68         }
69         final int hash = hash(k);
70         final Node<K, V> node;
71         final V value;
72         if ((node = this.getNode(hash, k)) != null && (value = node.value) != null) {
73             final V apply = (V)biFunction.apply(k, value);
74             if (apply != null) {
75                 node.value = apply;
76                 this.afterNodeAccess(node);
77                 return apply;
78             }
79             this.removeNode(hash, k, null, false, true);
80         }
81         return null;
82     }
HashMap 中用策略模式的函数

  可以看到,传入的 function 对象在某些执行路线下,会被执行 apply () 以使用里面的策略。

  外部可以这样调用:

 1 myMap.computeIfAbsent(keyC, new Function<String, String>(){
 2     @Override
 3     public String apply(String t) {
 4         return t + "2";
 5     }
 6 });//如果keyC没有对应值,则把值设为keyC和"2"这个字符串的连接
 7 
 8 myMap.computeIfPresent(keyC, new BiFunction<String, String, String>(){
 9     @Override
10     public String apply(String t, String u) {
11         return t + "," + u;
12     }
13 });//如果keyC有对应值,则把值设为原值和逗号和插入值这个字符串的连接
14 
15 myMap.computeIfAbsent(keyC, k -> k + "2");
16 
17 myMap.computeIfPresent(keyC, (v1, v2) -> v1 + "," + v2);
View Code

  前面 2 次函数调用用的是 Java 8 引入的新特性:Function 接口,它支持函数调用时传入策略函数,以改变内部的运行流程;

  后面 2 次函数调用同样用了 Java 8 引入的新特性:lambda 表达式,可以极大程度减少代码量。传入的表达式相当于声明了一个 Function 接口内部的 apply 函数。

  这样,Map 就无需为这些策略继承过多的子类,减少了无效的开发量。

  如果需要用默认 function,其实 Java 内部也有一些内部实现。

  现在咱们说说初始化策略类时传入 Function:

  “函数式接口” 是指仅仅只包含一个抽象方法,但是可以有多个非抽象方法 (也就是上面提到的默认方法) 的接口。 像这样的接口,可以被隐式转换为 lambda 表达式。java.lang.Runnable 与 java.util.concurrent.Callable 是函数式接口最典型的两个例子。Java 8 增加了一种特殊的注解 @FunctionalInterface, 但是这个注解通常不是必须的 (某些情况建议使用),只要接口只包含一个抽象方法,虚拟机会自动判断该接口为函数式接口。一般建议在接口上使用 @FunctionalInterface 注解进行声明,这样的话,编译器如果发现你标注了这个注解的接口有多于一个抽象方法的时候会报错的。

  像下列代码:

@FunctionalInterface
public interface Converter<F, T> {
    T convert(F from);
    void anotherMethod();
}

  就不可能编译通过,因为这里声明了多于 1 个的接口。

  像下列代码:

@FunctionalInterface
public interface Converter<F, T> {
  T convert(F from);
}

  就可以编译通过,还可以像下列代码那样调用:

// TODO 将数字字符串转换为整数类型
Converter<String, Integer> converter = (from) -> Integer.valueOf(from);
Integer converted = converter.convert("123");
System.out.println(converted.getClass()); //class java.lang.Integer

  像上述 Function 接口实际上都是使用了这个机制,用这个的话还可以自定义一些过于复杂的策略结构。

  优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。

  缺点: 1、策略类会增多。(Java 7 及以前就要重写一个类覆盖策略接口,容易导致这种问题;Java 8 及以后在函数调用时传入函数接口,或者通过:: 关键字传递方法或构造函数的引用,C 和 Python 有函数指针,相对来说没有类库膨胀的问题) 2、所有策略类都需要对外暴露。(这个其实问题不大,控制一下开发流程和访问权限就可以了)

  使用场景: 1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中选择一种。 3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

  注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

java - 策略模式、状态模式、卫语句,避免多重if-else(转)

java - 策略模式、状态模式、卫语句,避免多重if-else(转)

前言

当代码中出现多重if-else语句或者switch语句时。弊端之一:如果这样的代码出现在多处,那么一旦出现需求变更,就需要把所有地方的if-else或者switch代码进行更改,要是遗漏了某一处,那么程序就会出错。弊端之二:代码逻辑难以理解,可读性低。

 

卫语句

if (isSunshine()) {
    // 晴天时处理逻辑
  return xx;
}
if (isRain()) {
    // 下雨时处理逻辑
}
if (isOvercast()) {
    // 阴天时处理逻辑
}

 

 

策略模式

使用策略模式可以代替多重if-elseswitch语句,让代码维护变得更加简单。 
策略模式UML:

 

.环境(Context)角色:持有一个Strategy的引用
.抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现
.具体策略(ConcreteStrategy)角色:包装了相关的算法或行为

 

策略模式代码模板

 

package com.zzk.test.strategy.template;

import com.zzk.test.strategy.template.base.Strategy;

/**
 * @描述 环境角色
 */
public class Context {

    /**
     * 策略对象
     */
    private Strategy strategy;

    /**
     * @param strategy 具体策略对象
     */
    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    /**
     * @描述 执行策略方法
     */
    public void contextInterface() {
        strategy.strategyInterface();
    }
}

 

 

 

package com.zzk.test.strategy.template.base;

/**
 * @描述 抽象策略角色
 */
public interface Strategy {

    /**
     * @描述 策略方法
     */
    void strategyInterface();
}

 

 

package com.zzk.test.strategy.template;

import com.zzk.test.strategy.template.base.Strategy;

/**
 * @描述 具体策略类A
 */
public class ConcreteStrategyA implements Strategy {

    @Override
    public void strategyInterface() {
        // TODO Auto-generated method stub
    }
}

 

 

package com.zzk.test.strategy.template;

import com.zzk.test.strategy.template.base.Strategy;

/**
 * @描述 具体策略类B
 */
public class ConcreteStrategyB implements Strategy {

    @Override
    public void strategyInterface() {
        // TODO Auto-generated method stub
    }
}

 

 

package com.zzk.test.strategy.template;

import com.zzk.test.strategy.template.base.Strategy;

/**
 * @描述 具体策略类C
 */
public class ConcreteStrategyC implements Strategy {

    @Override
    public void strategyInterface() {
        // TODO Auto-generated method stub
    }
}

 

 

调用者

/**
     * @描述 使用策略模式:针对一组算法,将每一个算法封装到具有共同接口的独立的类
     */
    public static void useStrategy() {
        // 具体使用策略
        Strategy strategy = new ConcreteStrategyA();
        // 将策略放入环境中并执行策略
        new Context(strategy). contextInterface();
    }

 

 

状态模式

状态模式类图

 

 

环境(Context)角色,也成上下文:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态
抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的行为
具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为

 

 

策略模式代码模板:

package xyz.zeling.test.state.template.base;

/**
 * @description 抽象状态角色
 * @author zeling
 * @date 2018年1月14日 下午8:41:14
 */
public interface State {

    /**
     * @description 处理方法
     * @date 2018年1月14日 下午8:41:00
     */
    void handle();
}
package xyz.zeling.test.state.template;

import xyz.zeling.test.state.template.base.State;

/**
 * @description 具体状态类A
 * @author zeling
 * @date 2018年1月14日 下午8:45:00
 */
public class ConcreteStateA implements State {

    @Override
    public void handle() {
        // TODO Auto-generated method stub
    }
}

 

 

package xyz.zeling.test.state.template;

import xyz.zeling.test.state.template.base.State;

/**
 * @description 具体状态类A
 * @author zeling
 * @date 2018年1月14日 下午8:45:00
 */
public class ConcreteStateB implements State {

    @Override
    public void handle() {
        // TODO Auto-generated method stub
    }
}
package xyz.zeling.test.state.template;

import xyz.zeling.test.state.template.base.State;

/**
 * @description 具体状态类A
 * @author zeling
 * @date 2018年1月14日 下午8:45:00
 */
public class ConcreteStateC implements State {

    @Override
    public void handle() {
        // TODO Auto-generated method stub
    }
}
package xyz.zeling.test.state.template;

import xyz.zeling.test.state.template.base.State;

/**
 * @description 状态模式,环境角色类
 * @author zeling
 * @date 2018年1月14日 下午8:43:58
 */
public class Context {

    /**
     * 状态对象
     */
    private State state;

    /**
     * @description 设置状态
     * @date 2018年1月14日 下午9:13:20
     * @param state 具体状态
     */
    public void setState(State state) {
        this.state = state;
    }

    /**
     * @description 执行策略方法
     * @date 2018年1月14日 下午8:43:31
     */
    public void request() {
        state.handle();
    }
}

 

调用者

/**
     * @description 使用状态模式:状态模式,又称状态对象模式(Pattern of Objects for
     *              States),状态模式是对象的行为模式。状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样
     * @date 2018年1月14日 下午4:04:16
     */
    public static void useState() {
        // 具体使用状态
        State state = new ConcreteStateA();
        // 创建环境
        Context context = new Context();
        // 设置状态并执行
        context.setState(state);
        context.print();
    }

 

 

策略模式和状态模式的比较

讲真,我觉得它们都差不多啊,好难区别啊!!! 
不过,虽然讲不出来它们的区别是什么,但是有个例子可以很好的描述它们的区别

.状态模式:这个模式就好比员工申请离职单的流程,离职单到直接上级,这个状态就是直接上级批示,等直接上级审阅之后,通过了就到下一个状态。这一个个状态对应不同的处理,这是有顺序要求的。
.策略模式:这个模式好比于你假期要出国游玩,有日本、美国、新加坡等国家,你每到一个国家就执行不同的游玩策略,可以先去日本,也可以先去美国,没有顺序要求。

 

关于JAVA 中的设计模式三策略模式的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于23 种设计模式(12):策略模式、C++设计模式:策略模式、Fun 论设计模式之 6:策略模式(Strategy Pattern)与 Java 8 的 Function 类接口、java - 策略模式、状态模式、卫语句,避免多重if-else(转)等相关内容,可以在本站寻找。

本文标签: