【原】设计模式-策略模式(Strategy Model)

1、概述

在开发过程中常常会遇到类似问题,实现一个功能的时候往往有多种算法/方法(策略),我们可以根据环境的不同来使用不同的算法或策略来实现这一功能。

如在人物比较排序的实现中,我们有时需要把年龄做为比较的标准,或者有时又想将身高作为比较的标准,不同的比较标准也就衍生出了统一个比较目的的不同算法实现,在搜索问题中也是类似,有可能用到二分查找、顺序查找之类。通常较简单直接的思维便是将所有的算法(策略)写成一个类的方法,再通过客户端去调用;也可一将所有的算法全部封装在一个方法中用一堆的if...else...语句来判断。如果需要增加一种算法时,就需要去修改封装算法类的源代码;更换比较排序算法时,又需要去修改客户端代码。在算法类中封装了大量的算法,该类代码较复杂,维护困难;而且将策略包含在客户端,将导致客户端的程序庞大难以维护。

案例:出行旅游:出行旅游时,我们有以下几个策略可供选择:自行车、汽车、火车、飞机等,不同的方式,单都是去实现旅行这一个目的,选择策略的依据是时间、金钱、方便程度(对应到工程中就是需求的环境)。

2、目的

策略模式的目的在于:使算法和对象分离开来,能让算法独立于对象去变化。

核心思想其实是利用了面向对象编程多态的使用。

3、适用场景

当存在一下情况时使用Strategy模式:

  1)许多类实现统一目的,仅方式不同。“策略”提供了一种用多个行为中的一种来配置类的实现的方法,及一个系统可以动态的在多个算法中选择其中一种;

  2)需要同一中算法的不同变体。如:在比较对象时,采用的比较算法的不同,有可能需要去比较对象的成员变量;

  3)一个类或者方法中定义了多种行为,并且这些行为以多个判断语句来相互切换。可将相关的条件分支移入各自的Strategy类中去实现。

  4)算法的封装。通过策略模式向使用算法的客户隐藏算法的具体实现。

4、结构与组成

  策略模式的结构主要分类三个部分:

  抽象策略类(Strategy):定义所有实现算法的公共接口,Context直接使用接口调用ConcreteStrategy的具体算法。

  具体策略类(ConcreteStrategy):实现具体的算法,每个具体的算法类必须实现Strategy接口。

  环境类(Context):具体算法的使用类,需要用指定的一个ConcreteStrategy来配置。

4、实现

  一个班级的若干个学生,对他们进行排序分别按照名字、年龄、id排序(正序和倒序两种方式),如年龄和名字重复,则使用id进行升序排序。

  1 package com.cnblogs.vicentzh.strategymodel;
  2
  3 import java.util.ArrayList;
  4 import java.util.Collections;
  5 import java.util.Comparator;
  6 import java.util.Iterator;
  7 import java.util.List;
  8
  9 public class StrategyModel
 10 {
 11     /**
 12      * @Describe 客户端程序
 13      * @param args
 14      */
 15     public static void main(String[] args)
 16     {
 17         Student p1 = new Student("Tom",1,20);
 18         Student p2 = new Student("Tonny",2,50);
 19         Student p3 = new Student("Tom",5,30);
 20         Student p4 = new Student("John",8,10);
 21         Student p5 = new Student("Susan",9,15);
 22
 23         List<Student> students = new ArrayList<Student>();
 24         students.add(p1);
 25         students.add(p2);
 26         students.add(p3);
 27         students.add(p4);
 28         students.add(p5);
 29
 30         Context env = new Context();
 31
 32         //正序排列
 33         UpNameSort uns = new UpNameSort();
 34         env.setSortStrategy(uns);
 35         env.sort(students);
 36
 37         for (Iterator<Student> iter=students.iterator(); iter.hasNext();)
 38         {
 39             Student student = iter.next();
 40             System.out.println("id: " + student.getId() + ", name: " + student.getName()
 41                     + ", age:" + student.getAge());
 42         }
 43         System.out.println("-----------------------");
 44
 45         //倒序排列
 46         DownNameSort dns = new DownNameSort();
 47         env.setSortStrategy(dns);
 48         env.sort(students);
 49
 50         for (Iterator<Student> iter=students.iterator(); iter.hasNext();)
 51         {
 52             Student student = iter.next();
 53             System.out.println("id: " + student.getId() + ", name: " + student.getName()
 54                     + ", age:" + student.getAge());
 55         }
 56
 57     }
 58 }
 59
 60
 61 //需要用到的具体实例类
 62 class Student
 63 {
 64     private String name;
 65     private int age;
 66     private int id;
 67
 68     public Student(String name, int age, int id)
 69     {
 70         this.name = name;
 71         this.age = age;
 72         this.id = id;
 73     }
 74
 75     public String getName()
 76     {
 77         return name;
 78     }
 79     public int getAge()
 80     {
 81         return age;
 82     }
 83     public int getId()
 84     {
 85         return id;
 86     }
 87 }
 88
 89
 90 //抽象策略类(Strategy),即策略接口
 91 interface SortStrategy
 92 {
 93     public void sortStudent(List<Student> students);
 94 }
 95
 96
 97 //具体策略类(ConcreteStrategy),即具体正序算法实现类
 98 class UpNameSort implements SortStrategy,Comparator<Student>
 99 {
100     @Override
101     public void sortStudent(List<Student> students)
102     {
103         Collections.sort(students, this);
104     }
105
106     @Override
107     public int compare(Student o1, Student o2)
108     {
109         int result = o1.getName().compareTo(o2.getName());
110         if(0==result)
111         {
112             return o1.getId() - o2.getId();
113         }
114         return result;
115     }
116 }
117
118 //具体策略类(ConcreteStrategy),即具体倒序算法实现类
119 class DownNameSort implements SortStrategy, Comparator<Student>
120 {
121     @Override
122     public void sortStudent(List<Student> students)
123     {
124         Collections.sort(students, this);
125
126     }
127
128     @Override
129     public int compare(Student o1, Student o2)
130     {
131         int result = o2.getName().compareTo(o1.getName());
132         if(0==result)
133         {
134             return o1.getId() - o2.getId();
135         }
136         return result;
137     }
138 }
139
140 //使用环境类(Context)
141 //环境类根据接收到客户端具体的策略来对对象进行使用,同样也能用setSortStrategy方法
142 //随时根据客户端的需求去改变策略算法,并且不影响对象。
143 class Context
144 {
145     private SortStrategy concreteStrategy; //使用策略配置环境类
146
147     public Context(SortStrategy conSortStrategy)
148     {
149         this.concreteStrategy = conSortStrategy;
150     }
151
152     public Context()
153     {
154
155     }
156
157     //可随意定制化具体策略
158     public void setSortStrategy(SortStrategy conSortStrategy)
159     {
160         this.concreteStrategy = conSortStrategy;
161     }
162
163     //使用具体的策略(concreteStrategy)对对象进行操作
164     public void sort(List<Student> students)
165     {
166         concreteStrategy.sortStudent(students);
167     }
168 }

5、优缺点

  Strategy模式的优点:

  1)Strategy类将具体的算法进行抽象,为Context类提供了一系列可重用的算法或行为,同时屏蔽了底层算法实现的细节,同样也提高了代码的可重用性。

  2)通过Strategy模式,将具体策略的实现与应用的对象隔离开来,实现行为与对象的解耦;这样能是应用对象动态便捷的动态改变行为,使得算法易于切换、易于理解、易于扩展;

  3)消除了大量if...else...代码的冗余性和复杂性,以行为封装的形式使代码的逻辑表达更为清晰。

  Strategy模式的缺点:

  1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类:  模式的潜在缺点就是一个客户要选择一个合适的Strategy就必须知道这些Strategy到底有何不同。此时可能不得不向客户暴露具体的实现问题。

  2)Strategy和Context之间的通信开销 :无论各个ConcreteStrategy实现的算法是简单还是复杂, 它们都共享Strategy定义的接口。因此很可能某些 ConcreteStrategy不会都用到所有通过这个接口传递给它们的信息;简单的 ConcreteStrategy可能不使用其中的任何信息!这就意味着有时Context会创建和初始化一些永远不会用到的参数。

  3)策略模式将造成产生很多策略类:可以通过使用享元模式在一定程度上减少对象的数量。 增加了对象的数目 Strategy增加了一个应用中的对象的数目。

6、总结分析

  1)策略模式是一个比较容易理解和使用的设计模式,策略模式是对算法的封装,它把算法的实现和算法的使用对象解耦,委派给不同的对象管理。策略模式通常把一个系列的算法封装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。

  2)策略模式仅仅封装算法,提供新算法插入到已有系统中,以及老算法从系统中“换代”和“退休”的方便。

  3)在策略模式中,策略模式并不决定在何时使用何种算法,算法的选择由客户端来决定。这在一定程度上提高了系统的灵活性,但是客户端需要理解所有具体策略类之间的区别,以便选择合适的算法,这也是策略模式的缺点之一,在一定程度上增加了客户端的使用难度。

作者:vincentzh

出处:http://www.cnblogs.com/vincentzh/

本文以学习、研究和分享为主,如需转载,请联系本人,标明作者和出处,非商业用途!

时间: 2024-10-27 07:10:24

【原】设计模式-策略模式(Strategy Model)的相关文章

设计模式 - 策略模式(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()方法,

设计模式---策略模式Strategy(对象行为型)

1. 概述 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理. 2. 应用场景 (1)多个类只区别在表现行为不同,在运行时动态选择具体要执行的行为. (2)需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现. (3)对客户隐藏具体策略(算法)的实现细节,彼此完全独立. 3. 示例 出行旅游:我们可以有几个策略可以考虑:可

说说设计模式~策略模式(Strategy)

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.而对于客户端(UI)来说,可以通过IOC再配合工厂模块,实现动态策略的切换,策略模块通常于一个抽象策略对象(interface or abstract class),多个具体策略对象(implement class )和一个调用策略的入口组成. 何时能用到它? 对于UI来说,可能一个功能会有多种实现方式,而且实现方式可能还会有扩展,例如,一个ATM机,它目前支持工行,建行,家行,以后可能又出现了占占银行,而这时,ATM

设计模式--策略模式(strategy)

1.策略模式(strategy ['stræt?d?i]) 我的理解是:方案候选模式 (反正关键就是有很多的候选,哈哈) 看了很多例子,都是在说鸭子的,那个例子很好,然后我就照葫芦画瓢了, 他们生产鸭子,我们就制造人 所以,父类 Person类就出来了 1 public abstract class Person { 2 //唱歌可就不一样了,唱法不同,唱功不同:而且哑巴不能唱歌 3 public void singing(){ 4 System.out.println("我要唱歌")

设计模式-策略模式Strategy以及消灭if else

概述 如果在开发过程中,出现大量的if else或者switch case 语句,如果这些语句块中的代码并不是包含业务逻辑,只是单纯的分流方法,那么,每一个语句块中都是一个算法或者叫策略. 背景 比如在最近项目中遇到的问题.一个二维码字符串解析的方法: 微信的二维码扫描结果包含"WeChat",解析规则是拿着文本到微信服务器解析,返回解析对象. 支付宝二维码扫描结果包含"Alipay",解析规则是使用"->"分割字符串得到解析对象. 最简单

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

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

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

先说几个例子,让大家对策略模式有个感性的认识:比如玩RPG游戏时,一个人物可以拥有多种武器,但是攻击时只能使用一把武器,切换武器的过程其实就是一个策略模式的应用. 故事案例:鸭子很多种(活生生的鸭子,橡皮鸭,模型鸭,木头鸭...),共性是可以swim,display(即给别人看),活生生的鸭子可以嘎嘎叫,橡皮鸭子可以吱吱叫,模型鸭可以飞,木头鸭什么特别之处都没有,那我们怎么处理这个问题呢? 思路一:鸭子作为一个抽象类(Duck),然后这些具体的鸭子就继承他,并重新新增一些自己特有的方法.(好像感

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

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

设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕该功能.如查找.排序等,一种经常使用的方法是硬编码(Hard Coding)在一个类中,如须要提供多种查找算法,能够将这些算法写到一个类中,在该类中提供多个方法,每个方法相应一个详细的查找算法:当然也能够将这些查找算法封装在一个统一的方法中,通过if-else-或者case等条件推断语句来进行选择.