(定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。)
 
例:button 与 listener ,在使用时具体根据情况实例化listener,做不同的操作。
背景
在软件开发中常常遇到这种情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能。如查找、排序等,一种常用的方法是硬编码(Hard Coding)在一个类中,如需要提供多种查找算法,可以将这些算法写到一个类中,在该类中提供多个方法,每一个方法对应一个具体的查找算法;当然也可以将这些查找算法封装在一个统一的方法中,通过if…else…或者case等条件判断语句来进行选择。
这两种实现方法我们都可以称之为硬编码,如果需要增加一种新的查找算法,需要修改封装算法类的源代码;更换查找算法,也需要修改客户端调用代码。在这个算法类中封装了大量查找算法,该类代码将较复杂,维护较为困难。如果我们将这些策略包含在客户端,这种做法更不可取,将导致客户端程序庞大而且难以维护,如果存在大量可供选择的算法时问题将变得更加严重。
 
问题
如何让算法和对象分开来,使得算法可以独立于使用它的客户而变化?
 
方案
把一个类中经常改变或者将来可能改变的部分提取出来,作为一个接口,然后在类中包含这个对象的实例,这样类的实例在运行时就可以随意调用实现了这个接口的类的行为。
比如定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换,使得算法可独立于使用它的客户而变化。这就是策略模式。
 
适用情况
许多相关的类仅仅是行为有异。 “策略”提供了一种用多个行为中的一个行为来配置一个类的方法。即一个系统需要动态地在几种算法中选择一种。
当一个应用程序需要实现一种特定的服务或者功能,而且该程序有多种实现方式时使用。
一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。
 
优点
1、可以动态的改变对象的行为
缺点
1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类
2、策略模式将造成产生很多策略类
 
组成
环境类(Context):用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。
抽象策略类(Strategy):定义所有支持的算法的公共接口。 Context使用这个接口来调用某ConcreteStrategy定义的算法。
具体策略类(ConcreteStrategy):以Strategy接口实现某具体算法。
 
应用
场景如下,刘备要到江东娶老婆了,走之前诸葛亮给赵云三个锦囊妙计,说是按天机拆开能解决棘手问题。场景中出现三个要素:三个妙计(具体策略类)、一个锦囊(环境类)、刘备(调用者)。
 
抽象策略类(Strategy)
public interface Strategy {
public void operate();
}
三个实现类(ConcreteStrategy):
妙计一:初到吴国
public class BackDoor implements IStrategy {
@Override
public void operate() {
System.out.println("找乔国老帮忙,让吴国太给孙权施加压力,使孙权不能杀刘备");
}
}
妙计二:求吴国太开绿灯放行

 public class GivenGreenLight implements IStrategy {
@Override
public void operate() {
System.out.println("求吴国太开个绿灯,放行");
}
}
妙计三:孙夫人断后,挡住追兵
 public class BlackEnemy implements IStrategy {
@Override
public void operate() {
System.out.println("孙夫人断后,挡住追兵");
}
}

环境类(Context)

 public class Context {
private Strategy strategy;
//构造函数,要你使用哪个妙计
public Context(Strategy strategy){
this.strategy = strategy;
}
public void setStrategy(Strategy strategy){
this.strategy = strategy;
}
public void operate(){
this.strategy.operate();
}
}

下面就是使用的情况了

 public class LiuBei {  

 public static void main(String[] args) {
Context context; System.out.println("----------刚到吴国使用第一个锦囊---------------");
context = new Context(new BackDoor());
context.operate();
System.out.println("\n"); System.out.println("----------刘备乐不思蜀使用第二个锦囊---------------");
context.setStrategy(new GivenGreenLight());
context.operate();
System.out.println("\n"); System.out.println("----------孙权的追兵来了,使用第三个锦囊---------------");
context.setStrategy(new BlackEnemy());
context.operate();
System.out.println("\n");
}
}
三招下来,搞得的周郎是“赔了夫人又折兵”。
 
以上就是策略模式,多种不同解决方案动态切换,起到改变对象行为的效果。
 

策略模式(Strategy)(策略类,场景不同策略不同,环境策略分离组合,)的更多相关文章

  1. 面向对象设计模式--策略模式Strategy

    策略模式的UML类图(VS2013 C++版本): 策略模式的重点:每个策略对象封装一个算法,有多少个算法就有多少个对象.策略模式的意图是封装算法.要从“抽象不仅面对状态(字段.属性)还面对行为(算法 ...

  2. 设计模式(一):“穿越火线”中的“策略模式”(Strategy Pattern)

    在前段时间呢陆陆续续的更新了一系列关于重构的文章.在重构我们既有的代码时,往往会用到设计模式.在之前重构系列的博客中,我们在重构时用到了“工厂模式”.“策略模式”.“状态模式”等.当然在重构时,有的地 ...

  3. 策略模式 Strategy 政策Policy 行为型 设计模式(二十五)

    策略模式 Strategy   与策略相关的常见词汇有:营销策略.折扣策略.教学策略.记忆策略.学习策略.... “策略”意味着分情况讨论,而不是一概而论 面对不同年龄段的人,面对不同的商品,必然将会 ...

  4. 策略模式-Strategy(Java实现)

    策略模式-Strategy 在策略模式中,一个类(策略使用者)可以更改自己的执行策略. 比如以排序算法为例子, 多种排序算法都归属于排序算法, 但是实现的算法细节不同, 使用者可以很轻松地替换策略, ...

  5. [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型)

    [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模 ...

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

    在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式. 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 ...

  7. 24种设计模式-策略模式(Strategy Pattern)

    一.优点: 1. 策略模式提供了管理相关的算法族的办法.策略类的等级结构定义了一个算法或行为族.恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码. 2. 策略模式提供了可以替换继承关系的 ...

  8. 【转】设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

    设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成 ...

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

    设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕 ...

  10. HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern)

    策略模式(Strategy Pattern): 定义了了算法簇,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户端. 第一个设计原则:找出应用中可能需要变化之处,把他们独立 ...

随机推荐

  1. js实现iframe刷新

    今天要用到iframe的框架刷新,在网上找到了关于这方面内容,整理如下: (1)一般页面的刷新——reload 方法,该方法强迫浏览器刷新当前页面. 语法:location.reload([bForc ...

  2. 主机入侵防御系统(HIPS)分析

    主机入侵防御系统(Host Intrusion Prevent System,HIPS)是近几年出现并迅速发展的新兴产物,与传统意义的防火墙和杀毒软件不同,它并不具备特征码扫描和主动杀毒等功能,所以想 ...

  3. 用Spire.PDF提取PDF里的PNG图片

    用Nuget抓取类库,FreeSpire.PDF就可以 代码如下 , 亲测可以抓取PNG图形,即使原图是JPG,也会存成PNG格式输出: //加载PDF文档 PdfDocument doc = new ...

  4. uploadify附件上传 传参

    首先 在刚加载jsp时就加入上传方法,所以 formDate 中的参数 zFileName是页面刚加载时 exp1的值 ,后来通过js方法赋值不被读过来,如果 你想要获得这个值,可在 调用upload ...

  5. Python学习day37-并发编程(3)

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  6. MFC中使用FLASH相关

    出自http://my.oschina.net/ypimgt/blog/62573 一.准备工作 第一步:下载并安装Adobe Flash Player. 从官方网站(http://get.adobe ...

  7. java linkedlist和arraylist添加元素时性能比较

  8. 高德地图定位不到 报错 location Error, ErrCode:7, errInfo:KEY错误 请到http://lbs.amap.com/api/android-location-sdk/abouterrorcode/查看错误码说明.

    出现该问题的可能是高德地图的配置不准确: 仔细配对一下 看sha1 是否是通过应用签名生成的  要区分发布版的sha1 跟调试版的sha1  是不相同的 (小编我第一次反这种错误的时候 是因为我把高得 ...

  9. wpf listbox touch 整个窗口移动

    工作中遇到遇到,在有listbox中的地方,touch listbox的时候  可以把整个窗体都移动了,解决方案如下: /// <summary> /// prevent the rubb ...

  10. Innodb_buffer_pool_read

    > show status like 'Innodb_buffer_pool_read_%'; +---------------------------------------+-------- ...