简单工厂模式&策略模式-简介与区别

时间:2021-11-01 00:54:47

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

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

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

不同点:工厂模式仅提供具体的实例对象,怎么使用这个对象是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. &lbrack;C&num;&rsqb;设计模式-简单工厂-创建型模式

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

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

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

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

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

  7. 设计模式之&mdash&semi;&mdash&semi;浅谈strategy模式&lpar;策略模式&rpar;

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

  8. Go---设计模式&lpar;策略模式&rpar;

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

  9. &lbrack;Python模式&rsqb;策略模式

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

随机推荐

  1. Ice-E&lpar;Embedded Internet Communications Engine&rpar;移植到s3c2440A(arm9)linux(2&period;6&period;12)上的

    2009-03-26 18:31:31 原文链接 1.前言 ICE-E是ICE在嵌入式上运行的一个版本,与ICE比较如下: Category Ice 3.3.0 Ice-E 1.3.0 Thread ...

  2. 用jquery实现瀑布流案例

    一.瀑布流是我们常见的案例,这里主要讲述,用jquery的方式实现瀑布流的功能! 引言:我们经常见到很多网站的瀑布流功能,如淘宝.京东这些商品等等.. 实现它我们首先考虑几个问题:1.获取到数据   ...

  3. PHP导出数据到Excel

    <?php date_default_timezone_set('PRC'); $filename="info.xls";//先定义一个excel文件 header(&quo ...

  4. express-5 质量保证&lpar;2&rpar;

    跨页测试 跨页测试更有挑战性,因为需要你控制和观测浏览器. 现在设置一个跨页测试情境的例子.比如,你的网站上有一个包含联系表单的Request Group Rate页面.营销部门想知道客户是从哪个页面 ...

  5. 微信网页授权获取用户基本信息--PHP

    现在就说说怎么通过网页授权获取用户基本信息(国家,省,市,昵称)等. 必要条件: 1)公众号认证 2)有网页授权获取用户基本信息的权限接口 注意:最近有朋友说:在公众平台申请的测试号,会出现无法取到用 ...

  6. CentOS 6下配置本地用户访问vsftpd并赋予写权限

    一.安装并测试可用性 1.安装命令 yum install vsftpd 2.配置防火墙,加入一行 -A INPUT -p tcp -m tcp --dport 21 -j ACCEPT 在其它机测试 ...

  7. 【NOIP2015】反思&plus;题解

    D1T1> 神奇的幻方 模拟即可. #include <cstdio> #include <cstring> #include <algorithm> #de ...

  8. js面向对象-原型链

    var Person = function (name) { this.name = name; } Person.prototype.say = function () { console.log( ...

  9. if判断,switch语句

    if ; else if; else; 判断操作: 格式示例: public class scanner { public static void main(String[] args){ int a ...

  10. css3-盒模型display&colon;-webkit-box&semi;的使用

    提到移动布局不得不提到盒模型display:-webkit-box;这个属性,在移动布局中浮动已经不在重要,相反自适应成为主要的需求,所以display:-webkit-box;变得尤为重要. box ...