设计模式之 - 策略模式(Strategy Pattern)

引入:项目中涉及到工作流,当然这个工作流的实现是由用户根据不同的策略或者说方式传入处理这个事件的人的审批链,后台在存储过程中进行解析,然后生成最终的审批链,在系统中流转进行审批。 比如审批链: 张三 -> 李四 -> 王五

由于很多外部系统接入,所以系统提供多种审批链的生成方式供外部系统选择,比如 1. 已经定好的好审批链的(叫做模板)传入模板 ID 系统就可以根据传入的模板生成审批链; 2. 外部系统自定义审批链,则 外部系统直接传入审批  链,张三 -> 李四 -> 王五 ,我们系统进行解析存储。

最近坐在旁边的一哥们做这一块,于是乎这几天耳边总是“策略”二字。因为当时不了解策略模式,觉得很有趣,那么多处理方式如何能调用到目标类进行处理,所以昨晚1点多睡不着,决定来学习下这个设计模式- 策略模式。

书中定义: 定义一系列的算法,将每一个算法封装起来,并让它们可以互相替换。策略模式让算法独立于使用它的客户而变化,是一种对象的行为模式。下面以排序算法来学习下策略模式。

如图是网上找到的一段资料:

排序算法配合策略模式代码实现

1. 策略模式一般包括一个环境类即为使用算法的角色,它在解决问题的时候采用多种策略。在其中维护一个抽象策略的引用实例,用于定义采用的所采用的策略,下文中定义类名为 Context。

2. 抽象类或者接口,为所支持的算法声明抽象方法,是所有策略类的父类 ,我们使用Sort。

3. 具体的策略类,实现了上面的接口或者继承抽象类,实现其定义的抽象算法,在运行时具体类中的方法覆盖实现的抽象方法来完成某个业务处理。

(1) 环境类代码

package cn.aries.pattern.StrategyPattern;

public class Context {

    private Sort sortStrategy;

    public Context(Sort sortStrategy) {
        this.sortStrategy = sortStrategy;
    }

    public int[] sort(int[] arr){
        return sortStrategy.sort(arr);
    }
}

(2) 策略接口代码

package cn.aries.pattern.StrategyPattern;

public interface Sort {
    public int[] sort(int[] arr);
}

(3) 排序算法代码

a. 选择排序

package cn.aries.pattern.StrategyPattern;

public class SelectionSort implements Sort {
    /**
     * 选择排序
     */
    @Override
    public int[] sort(int[] arr) {
        int len = arr.length;
        int temp;

        for (int i = 0; i < len; i++) {
            temp = arr[i];
            int index = i;
            for (int j = i + 1; j < len; j++) {
                if (arr[j] < temp) {
                    temp = arr[j];
                    index = j;
                }
            }
            arr[index] = arr[i];
            arr[i] = temp;
        }
        System.out.println("this is selection sort !");
        return arr;
    }
}

b. 冒泡排序

package cn.aries.pattern.StrategyPattern;

public class BubbleSort implements Sort{

    /**
     * 冒泡排序
     */
    @Override
    public int[] sort(int[] arr) {
        int len = arr.length;
        for (int i = 0; i < len; i++) {
            for (int j = i+1; j < len; j++) {
                int temp;
                if(arr[i] > arr[j]){
                    temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        System.out.println("this is bubble sort !");
        return arr;
    }
}

c. 插入排序

package cn.aries.pattern.StrategyPattern;

public class InsertionSort implements Sort {

    /**
     * 插入排序法
     */
    @Override
    public int[] sort(int[] arr) {
        int len = arr.length;

        for (int i = 1; i < len; i++) {
            int temp = arr[i];
            int j;
            for (j = i; j > 0; j--) {
                if (arr[j - 1] > temp) {
                    arr[j] = arr[j - 1];
                } else {
                    break;
                }
            }
            arr[j] = temp;
        }
        System.out.println("this is insertion sort !");
        return arr;
    }
}

(4) 测试代码

package cn.aries.pattern.StrategyPattern;

public class App {
    public static void main(String[] args) {
        int[] arr = {8,4,5,2,62,2};     //具体的这个策略类调用可以在配置文件中设定,这里创建不同的排序算法实例就会调用的不同策略的排序算法
        Sort sortStrategy = new SelectionSort();
        Content content = new Content(sortStrategy);
        printArray(content.sort(arr));
    }

    public static void printArray(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + ",");
        }
    }
}

以上代码就是使用策略模式实现不同排序方法的调用。如果引入新的排序算法,对系统无任何影响,之需要添加一个新的具体策略类,在该策略类中封装新的算法,然后修改对应的配置文件应用该策略即可。

分析策略模式的优缺点

优点:

  1. 提供了对“开闭原则” 的完美支持,在不修改原代码的基础上,灵活的新增算法或者行为。

  2. 其定义了一个算法或者行为族,可以将公用的代码提取到继承的父类中,从了避免了重复的代码。

  3. 其将每个算法或者行为封装为一个类,就是一个类只做一间事情,符合“单一职责”原则。

  4. 可以避免使用多重条件转换语句if(){}else{},将选择使用什么算法的行为逻辑和算法分开,更易于维护。

缺点:

  客户端必须知道所有的策略类,并自行的决定选择使用哪一个策略类。客户端必须理解这些算法的区别,以便使用的使用选择恰当的算法类,就是策略模式只适用于客户端知道所有的算法和行为的情况。

回到开始项目中策略模式的运用

1. 每一个外部系统接入的时候,已经定义好了使用什么策略,然后将对应的策略写入数据库。

2. 每一个策略类都配置在了xml文件中。

3. 当外部系统提交数据过来的时候,根据外部系统名称到数据库中查找当时接入系统时选择的策略名称 strategyName 。

4. 在要调用策略的位置使用上下午容器ac.getBean("strategyName");获取到具体的策略类,就可以根据客户需求使用目标算法或者方式完成业务流程,类似如下代码:

其实最终的结论,在使用策略的时候,一个业务可能有多中执行路径或者执行方式供选择(也就是多个策略),但是具体走那一条,还是需要在调用的时候就间接的表示清楚,到此心中的谜团解开了。

时间: 2024-10-08 20:31:31

设计模式之 - 策略模式(Strategy Pattern)的相关文章

如何让孩子爱上设计模式 ——14.策略模式(Strategy Pattern)

如何让孩子爱上设计模式 --14.策略模式(Strategy Pattern) 描述性文字 本节讲解的是行为型设计模式中的第一个模式: 策略模式, 这个模式非常简单,也很好理解. 定义一系列的算法,把每个算法封装起来,并使得他们可以相互替换, 让算法独立于使用它的客户而变化. 一般用来替换if-else,个人感觉是面向过程与面向对象思想的 过渡,这里举个简易计算器的栗子,帮助理解~ 普通的if-else/switch计算器 普通的面向过程if-else简易计算器代码如下: 运行结果如下: 这里我

二十四种设计模式:策略模式(Strategy Pattern)

策略模式(Strategy Pattern) 介绍定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换.本模式使得算法的变化可独立于使用它的客户. 示例有一个Message实体类,对它的操作有Insert()和Get()方法,持久化数据在SqlServer数据库中或Xml文件里(两种可互换的算法).由客户端决定使用哪种算法. MessageModel using System; using System.Collections.Generic; using System.Text; na

设计模式 - 策略模式(Strategy Pattern) 具体解释

策略模式(Strategy Pattern) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26577879 本文版权全部, 禁止转载, 如有须要, 请站内联系. 策略模式: 定义了算法族, 分别封装起来, 让它们之间能够相互替换, 此模式让算法的变化独立于使用算法的客户. 对于父类的子类族须要常常扩展新的功能, 为了使用父类比較灵活的加入子类, 把父类的行为写成接口(interface)的形式; 使用set()方法

设计模式 - 策略模式(Strategy Pattern) 详解

策略模式(Strategy Pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26577879 本文版权所有, 禁止转载, 如有需要, 请站内联系. 策略模式: 定义了算法族, 分别封装起来, 让它们之间可以相互替换, 此模式让算法的变化独立于使用算法的客户. 对于父类的子类族需要经常扩展新的功能, 为了使用父类比较灵活的添加子类, 把父类的行为写成接口(interface)的形式; 使用set()方法,

JAVA设计模式之策略模式 - Strategy

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式. 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象.策略对象改变 context 对象的执行算法. 介绍 什么是策略模式(Strategy Pattern) 在软件开发过程中常常遇到这样的情况, 实现某一个功能有很多种算法或实现策略, 我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能. 如果将这些算法或者策略抽象

设计模式之策略模式(Strategy)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

策略模式(Strategy Pattern)

策略模式(Strategy Pattern) 抛开晦涩的定义,首先看一个例子: 我们想要创建一个模拟鸭子的游戏,在这个游戏中,会有各种类型的鸭子,比如mallard duck,red head duck,rubber duck(除了rubber duck(橡皮鸭),看见这其余两种鸭子很好奇,于是查找相关图片,发现mallard duck是绿头鸭,red head duck是红头鸭,自己生活中还没有见过,有趣,哈哈!三种鸭子图片如下所示). 回归话题,在这个模拟鸭子的游戏中,各种鸭子均有两种能力,

设计模式---策略模式Strategy Pattern

策略模式 定义:定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换.本模式使得算法可独立于使用它的客户而变化. 问题:有一个鸭子类定义了鸭子的种种行为,包括swim(),quack(),fly(),但是,并不是所有的鸭子都会飞行(fly)或者叫(quack),在这里,我们认为所有的鸭子都会浮在水面上(swim).如何实现各种不同的鸭子的不同的表现. 解决方法:第一个想到的会使继承,在鸭子父类中定义好所有的方法,在实现鸭子子类的过程中,对不满足于具体的鸭子的行为进行覆盖,但是在这种方法

设计模式(行为型)之策略模式(Strategy Pattern)

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbober] 阅读前一篇<设计模式(行为型)之迭代器模式(Iterator Pattern)>http://blog.csdn.net/yanbober/article/details/45497881 概述 使用策略模式可以定义一些独立的类来封装不同的算法,每一个类封装一种具体的算法,在这里,每一个封

设计模式之一:策略模式(Strategy Pattern)

在介绍策略模式之前先说下两个设计原则: 1.  Identify the aspects of your application that vary and separate them from what  stays the same.找到系统中变化的部分,将变化的部分同其它稳定的部分隔开. 2.  Program to an interface, not an implementation.面向接口编程,而不要面向实现编程. 那什么是策略模式呢? The Strategy Pattern d