前言:两种模式的相似点与不同点

不得不说,这两种模式真的很像。

相似点:都用到了面向对象的继承、多态、抽象,都拥有相似的结构。

不同点:工厂模式仅提供具体的实例对象,怎么使用这个对象是client的自由,策略模式client可以通过策略类来决定使用哪个实例的哪个方法。

一、两种模式的公共相同部分

下面,我们假设有一台红白机,里面有一些游戏,每个游戏拥有play(玩)和uninstall(卸载)两个方法。

按照工厂和策略模式,我们抽象出来一个Game接口:


public interface Game { void play(); void uninstall(); }

然后,我们假设游戏机里有魂斗罗、马戏团、默认的俄罗斯方块三款游戏,每个游戏有不同的玩法和卸载算法:


// 魂斗罗,实现Game
public class Hundouluo implements Game {
@Override
public void play() {
System.out.println("游戏:魂斗罗...playing");
} @Override
public void uninstall() {
System.out.println("游戏:魂斗罗...卸载");
}
} // 马戏团,实现Game
public class Maxituan implements Game { @Override
public void play() {
System.out.println("游戏:马戏团...playing");
} @Override
public void uninstall() {
System.out.println("游戏:马戏团...卸载");
} } // 默认的俄罗斯方块,实现Game
public class Default implements Game { @Override
public void play() {
System.out.println("游戏:俄罗斯方块...playing");
} @Override
public void uninstall() {
System.out.println("游戏:俄罗斯方块...卸载");
} }

ok,工厂模式和策略模式的相同部分就已经写好了,通过上面的代码,我们可以发现这两种模式都是需要把相同的部分抽象出来,通过多态来实例化不同的对象,调用其对应的实现。

二、两种模式的不同部分的实现

2.1:工厂模式

工厂需要一个工厂类,用来返回具体的实例对象用,代码如下:


public class GameFactory { public static Game getGame(String name) {
switch (name) { //根据传来的游戏名(这里偷懒用了首字母),来实例化具体的对象
case "hdl":
return new Hundouluo();
case "mxt":
return new Maxituan();
default:
return new Default();
}
} }

2.2:策略模式

策略模式需要策略类来封装具体的行为(方法),并且还可以指定使用哪个实例的哪个行为,代码如下:


// 为了和工厂做充分的区分,这里定义了两个类型的context,分别维护一个行为算法(也就是方法函数,其次建立两个context是为了说明问题,实际使用时可能不需要这么多) // 用来维护play这个算法的实现
public class PlayContext { private Game game; public PlayContext() {
this.game = new Default();
} public PlayContext(Game game) {
this.game = game; // 这里根据传入的具体实例赋值
} public void trigger() {
this.game.play(); // 这里是对行为的封装,只提供play方法的触发
} } // 用来维护uninstall这个算法的实现
public class UninstallContext { private Game game; public UninstallContext() {
this.game = new Default();
} public UninstallContext(Game game) {
this.game = game; // 这里根据传入的具体实例赋值
} public void trigger() {
this.game.uninstall(); // 这里是对行为的封装,只提供uninstall方法的触发
} }

测试代码:


new PlayContext(new Hundouluo()).trigger();
new UninstallContext(new Hundouluo()).trigger();
new PlayContext(new Maxituan()).trigger();
new UninstallContext(new Maxituan()).trigger();

运行结果:


游戏:魂斗罗...playing
游戏:魂斗罗...卸载
游戏:马戏团...playing
游戏:马戏团...卸载

通过上面的实验,和对比,会发现,工厂模式是简单的对实例的封装,而策略模式更在意的是对具体实例的具体行为(方法)的封装。

还有一种情况就是利用工厂模式的思想,实现的策略模式,我们现在来改造下上面的PlayContext源码:


public class PlayContext { private Game game; public PlayContext() {
this.game = new Default();
} public PlayContext(String name) {
switch (name) { //根据传来的游戏名(这里偷懒用了首字母),来实例化具体的对象
case "hdl":
this.game = new Hundouluo();
break;
case "mxt":
this.game = new Maxituan();
break;
default:
this.game = new Default();
}
} public void trigger() {
this.game.play(); // 这里是对行为的封装,只提供play方法的触发
} }

测试类:


new PlayContext("hdl").trigger();
new UninstallContext(new Hundouluo()).trigger();
new PlayContext("mxt").trigger();
new UninstallContext(new Maxituan()).trigger();

测试结果:


游戏:魂斗罗...playing
游戏:魂斗罗...卸载
游戏:马戏团...playing
游戏:马戏团...卸载

三、总结

策略模式是一种定义一系列算法的方法,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有算法,减少了各种算法类与使用算法类之间的耦合。

工厂模式仅提供对应的实例,不对其方法做封装,减少了具体实现的实例与使用实例的业务方的耦合。

(↑描述待改进)

简单工厂模式&策略模式-简介与区别的更多相关文章

  1. 工厂模式&策略模式。

    抽象.封装,具体事情做得越多,越容易犯错误.这每个做过具体工作的人都深有体会,相反,官做得越高,说出的话越抽象越笼统,犯错误可能性就越少.好象我们从编程序中也能悟出人生道理.(百度百科) 不断抽象封装 ...

  2. 3.js模式-策略模式

    1. 策略模式 策略模式定义一系列的算法,把它们封装起来,并且可以互相替换. var strategies = { isNonEmpty: function(value,errMsg){ if(val ...

  3. 命令模式 & 策略模式 & 模板方法

    一.策略模式 策略模式:封装易变化的算法,可互相替换. GoF<设计模式>中说道:定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换.该模式使得算法可独立于它们的客户变化. 比如 ...

  4. [C#]设计模式-简单工厂-创建型模式

    在设计模式当中有三大工厂,分别是 简单工厂.抽象工厂.工厂方法 这三种创建实例的设计模式,这里先从简单工厂将其,从名字就可以看出这是这三种工厂模式当中最为简单的一种实现. 简单工厂一般由以下几个对象组 ...

  5. &lt;大话设计模式&gt;工厂模式,策略模式

    第一章:工厂模式: 通过封装,继承,多态解耦合 业务逻辑和界面逻辑分开 用单独的类创造实例,工厂:创造实例 工厂模式还可以用反射来实现,nsstringFromClass UML类图 聚合表示一众弱的 ...

  6. 模板方法模式&amp;策略模式区别联系

    一.模板方法 模板方法模式:定义 一系列算法, 子类延伸实现.着重点在于:子类去处理不同的方法实现. 看下面例子. 假如一个支付 都包含三个部分: 生成订单 ---->调用API发起支付---- ...

  7. 设计模式之&mdash;&mdash;浅谈strategy模式(策略模式)

    strategy模式,即策略模式.个人觉得吧,策略模式更多的是一种思维方式. 首先我们要知道,为什么需要策略模式.举个例子,比如用程序输出今天下午去玩什么. PlayGame 玩游戏 package ...

  8. Go---设计模式(策略模式)

    策略模式定义了算法家族,在调用算法家族的时候不感知算法的变化,客户也不会受到影响. 下面用<大话设计模式>中的一个实例进行改写. 例:超市中经常进行促销活动,促销活动的促销方法就是一个个策 ...

  9. [Python模式]策略模式

    策略模式 定义了算法族,分别封装起来,让它们之间可以互相替换.此模式让算法的变化独立于使用算法的客户. 作为动态语言,Python实现策略模式非常容易,只要所有算法提供相同的函数即可. import ...

随机推荐

  1. thinkphp自定义分页效果

    TP自带了一个分页函数,挺方便使用的. 下面是我的使用方法: /*****************分页显示start*************************/ $arr_page=$this ...

  2. html本地服务器

    html本地服务器 http://files.cnblogs.com/files/douxuyao/Aws.rar

  3. Windows Phone 开发——相机功能开发

    相机功能是手机区别于PC的一大功能,在做手机应用时,如果合理的利用了拍照功能,可能会给自己的应用增色很多.使用Windows Phone的相机功能,有两种方法,一种是使用PhotoCamera类来构建 ...

  4. C# 中==与Equals方法比较

    先来段代码,如下: static void Main(string[] args) { string a = new string(new char[] { 'h', 'e', 'l', 'l', ' ...

  5. [连载]JavaScript讲义(03)--- JavaScript面向对象编程

  6. eclipse开发servlet应用,Tomcat无法访问jpg图片 ===第二版===

    之前版本中,设置完后,确实可以访问图片了,但是问题接着来了,那就是,无法访问servlet的服务了. 后来想了下,原因也挺好理解的,设置到了Tomcat目录,而项目没有部署,所以没能访问. 但是怎么两 ...

  7. uva 260 - Il Gioco dell&#39;X

    题解: 一定有人获胜,非黑即白:获胜条件为:black是由 上走到下,white是由 左走到右: #include <cstdio> using namespace std; int N; ...

  8. 基于visual Studio2013解决C语言竞赛题之0602最大值函数

     题目

  9. 2. ansible-playbook 条件语句-内部变量使用

    内部变量指的是把变量定义在playbook里面或者是执行结果作为变量 循环语句-标准Loops [root@LeoDevops playb]# cat p_loop.yaml - hosts: u12 ...

  10. 从 s = &quot;我爱北京天安门&quot; 中悟道了-----------迭代器操作print(c.__next__())的最!大!好!处!-----------------------------------------------------可以一个一个输出

    s = "我爱北京天安⻔"c = s.__iter__() # 获取迭代器# print(c) # 打印迭代器的地址# print(c.__next__()) # 打印迭代器中的下 ...