软件工程Strategy策略模式

更新时间:2023-07-28 23:06:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

strategy 策略行为型设计模式

摘要:

Strategy是属于设计模式中对象行为型模式,主要定义一系列的算法,把这些算法一个个封装成单独的类,并且使这些类可以相互替换,以达到能够使得算法的变化可独立于使用它的客户的目的。

关键字:

设计模式,定义算法,封装

引言:

Strategy应用比较广泛,比如,公司经营业务变化图,可能有两种实现方式,一种是线条曲线,另一种是框图(bar),这两种算法可以使用Strategy实现。还有一些使用如:Context,印刷图书,Strategy,使用某种技术的印刷设备,Algorithem,具体的印刷技术,如喷墨,胶印,IStrategy,印刷 正文:

行为型模式:

1.职责链模式 Chain of Responsibility 2.命令模式 Command 3.解释器模式 Interpreter 4.迭代器模式 Iterator 5.中介者模式 Mediator 6.备忘录模式 Memento 7.观察者模式 Observer 8.状态模式 State 9.策略模式 Strategy

10.模板方法模式 Template Method 11.访问者模式 Visitor

1.职责链模式 Chain of Responsibility

职责链模式使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦

合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 “击鼓传球”游戏就是职责链模式的一种应用,鼓起,球从人手中传递,鼓落,拿球的人要做某件事。

命令模式Command

命令模式将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;

可以对请求排队或记录请求日志,以及支持可撤销的操作。命令模式是对“行为的请求者”和“行为的实现者”进行了解耦。Invoker对象可以在不同的时刻指定、排列、执行操作,支持取消、重做的操作,支持事务,记录操作的日志.

解释器模式 Interpreter

解释器模式,给定一个语言,定义它的问法的一种表示,并定义一个解释器,这个解

释器使用该表示来解释语言中的句子。

一个特定类型的复杂问题频繁出现,这时我们可以用解释器模式将负责对象表述为一个简单的对象,再进行处理。正则表达式就是一个非常好的例子。

迭代器模式Iterator

迭代器模式提供了一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对

象的内部表示。当我们需要对聚集有多种方式遍历时,可以考虑用迭代器模式。迭代器模式提供“开始、下一个、是否结束、当前哪一项…”等统一的接口。

迭代器模式分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露内部结构,又可以让外部代码透明底访问集合内部的数据。松散了耦合性,做到了信息隐蔽。

比如老师向班长要一个学生花名册,班长可以按学号进行排列,也可以按姓名首字母进行排列,只要包括了全部学生就行了。

中介者模式 Mediator

中介者模式用一个中介对象来封装一系列的对象交互。中介者是各对象不需要显式地

相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

中介者模式,将多个对象之间的多对多的关系转变为了一对一的关系。对象间的相互通信,都需要通过中介者对象来完成,一个对象的增加和移除,不影响其他对象,这样就降低了他们之间的耦合。

备忘录模式 Memeton

备忘录模式在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保

存这个状态,这样以后就可以将该对象恢复到原先保存的状态了。

观察者模式 Observer

观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,

所有依赖它的对象都会得到通知,并被自动更新,

系统中有两个方面,其中一个方面依赖与另一个方面,我们把这两个方面抽象,是各自可以独立的变化和复用。

就像我们现在所用到的分层,不就是一层层的依赖么?还有系统组件升级,系统功能

也跟着变化,这也属于观察者模式。

状态模式 State

状态模式允许一个对象在其内部状态改变时改变它的行为,让对象看起来似乎修改了它的类。

状态模式就是把系统的多个状态分割开来,分布到State的子类中,消除了庞大的分支语句,减少了耦合,同时也很容易增加新的状态的和转换。

这就相当于一个Schedule或School Timetable一样,时间的改变,我们的行程或课程也随之改变。

策略模式 Strategy

策略模式定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。本模式使得算法的变化不会影响到使用算法的客户。

策略模式将每一个算法封装到一个具有公共接口的独立类中,解除了客户与具体算法的直接耦合,是客户改变算法更为容易。

策略模式+简单工厂+反射+配置文件可以组成更为灵活的方式。

模版方法模式 Template Method

模版方法模式定义一个操作的算法骨架,而将一些步骤延迟到子类中,模版方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 模版方法就是把不变的行为搬到了超类中,去除了子类中的重复代码。

多个客户去银行开户,大家都需要填写一个开户表单,表单的格式都是一样的,但是每个人填写的内容却是不同的,客户是需要填写不同的内容即可,而不是把整个表单抄一遍。

访问者模式 Visitor

访问者模式表示一个作用于某对象结构中的个各原色的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

访问者模式适用于数据结构相对稳定的系统。它是将数据结构和作用于结构上的操作分离开来,完成了解耦,可以是操作集合自由演化,但不适合更改数据结构。

(1)算法与对象的耦合

对象可能经常需要使用多种不同的算法,但是如果变化频繁,会将类型变得脆弱

(2)动机(Motivation)

在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担。如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?

(3) 意图(Intent)

定义一系列算法,把它们一个个封装起来,并且使它们可互相替换。该模式使得算法可独立于使用它的客户而变化。

(4)结构

Strategy的结构如下图所示

下面简要介绍一下以上类图中各个类的作用:

(1) Context类为上下文类,负责维护和更新算法所要处理的环境和数据。譬如对于图象压

缩来说,Context负责数据的提取、压缩参数的获得以及压缩以后善后工作等等; (2) Strategy代表抽象的算法,譬如对于图象压缩来说,它代表的就是图象压缩算法,至于具体那种压缩?JEPG压缩还是GIF压缩,Strategy类不关心,它只为具体的图象压缩算法提供统一的接口;

(3)ConcreteStrategyA、ConcreteStrategyB、ConcreteStrategyC则代表特别具体的算法。 Context类维护Strategy的一个引用(或者指针)。一旦Context所维护的上下文有变(譬如输入数据有变化),它就将这个职责转发给它的Strategy对象。Context的客户制定应该使用哪一种Strategy(算法)的方式是直接将它想要的具体的

Strategy (ConcreteStrategyA、ConcreteStrategyB、ConcreteStrategyC )装入Composition中。

(5)实用性

当存在一下情况时,适合使用Strategy模式

(a) 许多相关的类仅仅是行为上的差异。“策略”提供了一种用多个行为中的一个行为类配置一个类的方法;

(b) 需要使用一个算法的不同的变体。例如,您可能会定义一些反映不同空间/时间权衡的算法。当这些变体实现为一个算法的类层次时,可以使用策略模式;

(c) 算法使用客户不应该知道的具体的实现步骤,可以使用策略模式以免暴露复杂的、与算法相关的数据结构;

(d) 一个类定义了多种行为,并且为这些行为在这个类的操作中以多个条件语句的形式出现相关的条件分支移入它们各自的Strategy类中,以代替这些语句。 (6)作用

策略模式将类中的算法分离出放在一个单独的类中。不同的算法适用于不同的问题。如果所有的算法都集中在一个类中定会导致带有条件选择的杂乱的代码。策略模式使得客户端能够轻松的从一系列算法中找出适合自己的算法。这些算法可以不依赖他们用到的数据来表示。

(7)代码实现

using System;

using System.Collections.Generic; using System.Linq; using System.Text;

namespace Strategy {

// The Context class Context {

// Context state

public const int start = 5; public int Counter = 5;

// Strategy aggregation

IStrategy strategy = new Strategy1();

// Algorithm invokes a strategy method public int Algorithm() {

return strategy.Move(this); }

// Changing strategies

public void SwitchStrategy() {

if (strategy is Strategy1) strategy = new Strategy2(); else

strategy = new Strategy1(); } }

// Strategy interface interface IStrategy {

int Move (Context c); }

// Strategy 1

class Strategy1 : IStrategy {

public int Move (Context c) {

return ++c.Counter; } }

// Strategy 2

class Strategy2 : IStrategy {

public int Move (Context c) {

return --c.Counter ; } }

class Program {

static void Main(string[] args) {

Context context = new Context(); context.SwitchStrategy(); Random r = new Random(37);

for (int i=Context.start; i<=Context.start+15; i++)

{

if (r.Next(3) == 2) {

Console.Write("|| "); context.SwitchStrategy(); }

Console.Write(context.Algorithm() +" "); }

Console.WriteLine(); Console.ReadLine(); } } }

输出: /* Output

4 || 5 6 7 || 6 || 7 8 9 10 || 9 8 7 6 || 7 || 6 5 */

总结

Strategy模式的要点:

1、Strategy及其子类为组件提供了一系列可重用的算法,从而可以使得类型在运行时方便地根据需要在各个算法之间进行切换。所谓封装算法,支持算法的变化。

2、Strategy模式提供了用条件判断语句以外的另一中选择,消除条件判断语句,就是在解耦合。含有许多条件判断语句的代码通常都需要Strategy模式。

3、Strategy模式以算法为中心,可以和Factory Method联合使用,在工厂中使用配制文件对变化的点进行动态的配置。这样就使变化放到了运行时。 4、Strategy模式集中在算法的封装上

本文来源:https://www.bwwdw.com/article/4ndm.html

Top