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

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

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

不同点:工厂模式仅提供具体的实例对象,怎么使用这个对象是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. <大话设计模式>工厂模式,策略模式

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

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

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

  7. 设计模式之——浅谈strategy模式(策略模式)

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

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

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

  9. [Python模式]策略模式

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

随机推荐

  1. 随机分布 + action 计数

    For random samples from , use:  注意平方: sigma * np.random.randn(...) + mu 2.5*2.5 = 6.25 Two-by-four a ...

  2. java集成支付宝移动快捷支付时报错java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence

    出错原因是代码中的私钥设置错误,不是填原始的私钥,而是转换为PKCS8格式的私钥(Java格式的) ,改成后就会报创建交易异常了

  3. 【转】java.sql.SQLException: statement is closed语句被关闭 druid连接池报错

    我之前在用druid 1.0.28版本也出现过这个问题, 现象就是: 报这个错的时候, 往往会出现在一条毫无错误的sql执行上报错,  sql放到数据库上执行或者单独拎出来执行完全没问题, 但是为什么 ...

  4. 8.3 mysql 表操作

    库操作 一 系统数据库 information_schema: 虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数,如用户表信息.列信息.权限信息.字符信息等    performance_sch ...

  5. HDU 1071 The area (数学定积分)

    题意:求阴影部分面积. 析:没什么可说的,就是一个普通的定积分. 代码如下: #include <cstdio> #include <iostream> using names ...

  6. C++ 数据封装和抽象

    C++ 数据抽象 数据抽象是指,只向外界提供关键信息,并隐藏其后台的实现细节,即只表现必要的信息而不呈现细节. 数据抽象是一种依赖于接口和实现分离的编程(设计)技术. 让我们举一个现实生活中的真实例子 ...

  7. EventBus事件总线框架(发布者/订阅者模式,观察者模式)

    一. android应用内消息传递的方式: 1. handler方式-----------------不同线程间传递消息. 2. Interface接口回调方式-------任意两个对象. 3. In ...

  8. SqlServer循环执行存储过程

    begin --申明变量 ) declare @zycs int --赋值变量 --申明游标 declare order_cursor cursor for (select blh, zycs fro ...

  9. ASP.NET Core2基于RabbitMQ对Web前端实现推送功能

    在我们很多的Web应用中会遇到需要从后端将指定的数据或消息实时推送到前端,通常的做法是前端写个脚本定时到后端获取,或者借助WebSocket技术实现前后端实时通讯.因定时刷新的方法弊端很多(已不再采用 ...

  10. [转载]SQL Server行列转换实现

    可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )AS P 完整语法: table_source PIVOT( 聚合函数(value_ ...