前言:两种模式的相似点与不同点
不得不说,这两种模式真的很像。
相似点:都用到了面向对象的继承、多态、抽象,都拥有相似的结构。
不同点:工厂模式仅提供具体的实例对象,怎么使用这个对象是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
游戏:马戏团...卸载
三、总结
策略模式是一种定义一系列算法的方法,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有算法,减少了各种算法类与使用算法类之间的耦合。
工厂模式仅提供对应的实例,不对其方法做封装,减少了具体实现的实例与使用实例的业务方的耦合。
(↑描述待改进)
简单工厂模式&策略模式-简介与区别的更多相关文章
-
工厂模式&;策略模式。
抽象.封装,具体事情做得越多,越容易犯错误.这每个做过具体工作的人都深有体会,相反,官做得越高,说出的话越抽象越笼统,犯错误可能性就越少.好象我们从编程序中也能悟出人生道理.(百度百科) 不断抽象封装 ...
-
3.js模式-策略模式
1. 策略模式 策略模式定义一系列的算法,把它们封装起来,并且可以互相替换. var strategies = { isNonEmpty: function(value,errMsg){ if(val ...
-
命令模式 &; 策略模式 &; 模板方法
一.策略模式 策略模式:封装易变化的算法,可互相替换. GoF<设计模式>中说道:定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换.该模式使得算法可独立于它们的客户变化. 比如 ...
-
[C#]设计模式-简单工厂-创建型模式
在设计模式当中有三大工厂,分别是 简单工厂.抽象工厂.工厂方法 这三种创建实例的设计模式,这里先从简单工厂将其,从名字就可以看出这是这三种工厂模式当中最为简单的一种实现. 简单工厂一般由以下几个对象组 ...
-
<;大话设计模式>;工厂模式,策略模式
第一章:工厂模式: 通过封装,继承,多态解耦合 业务逻辑和界面逻辑分开 用单独的类创造实例,工厂:创造实例 工厂模式还可以用反射来实现,nsstringFromClass UML类图 聚合表示一众弱的 ...
-
模板方法模式&;策略模式区别联系
一.模板方法 模板方法模式:定义 一系列算法, 子类延伸实现.着重点在于:子类去处理不同的方法实现. 看下面例子. 假如一个支付 都包含三个部分: 生成订单 ---->调用API发起支付---- ...
-
设计模式之&mdash;&mdash;浅谈strategy模式(策略模式)
strategy模式,即策略模式.个人觉得吧,策略模式更多的是一种思维方式. 首先我们要知道,为什么需要策略模式.举个例子,比如用程序输出今天下午去玩什么. PlayGame 玩游戏 package ...
-
Go---设计模式(策略模式)
策略模式定义了算法家族,在调用算法家族的时候不感知算法的变化,客户也不会受到影响. 下面用<大话设计模式>中的一个实例进行改写. 例:超市中经常进行促销活动,促销活动的促销方法就是一个个策 ...
-
[Python模式]策略模式
策略模式 定义了算法族,分别封装起来,让它们之间可以互相替换.此模式让算法的变化独立于使用算法的客户. 作为动态语言,Python实现策略模式非常容易,只要所有算法提供相同的函数即可. import ...
随机推荐
-
Ice-E(Embedded Internet Communications Engine)移植到s3c2440A(arm9)linux(2.6.12)上的
2009-03-26 18:31:31 原文链接 1.前言 ICE-E是ICE在嵌入式上运行的一个版本,与ICE比较如下: Category Ice 3.3.0 Ice-E 1.3.0 Thread ...
-
用jquery实现瀑布流案例
一.瀑布流是我们常见的案例,这里主要讲述,用jquery的方式实现瀑布流的功能! 引言:我们经常见到很多网站的瀑布流功能,如淘宝.京东这些商品等等.. 实现它我们首先考虑几个问题:1.获取到数据 ...
-
PHP导出数据到Excel
<?php date_default_timezone_set('PRC'); $filename="info.xls";//先定义一个excel文件 header(&quo ...
-
express-5 质量保证(2)
跨页测试 跨页测试更有挑战性,因为需要你控制和观测浏览器. 现在设置一个跨页测试情境的例子.比如,你的网站上有一个包含联系表单的Request Group Rate页面.营销部门想知道客户是从哪个页面 ...
-
微信网页授权获取用户基本信息--PHP
现在就说说怎么通过网页授权获取用户基本信息(国家,省,市,昵称)等. 必要条件: 1)公众号认证 2)有网页授权获取用户基本信息的权限接口 注意:最近有朋友说:在公众平台申请的测试号,会出现无法取到用 ...
-
CentOS 6下配置本地用户访问vsftpd并赋予写权限
一.安装并测试可用性 1.安装命令 yum install vsftpd 2.配置防火墙,加入一行 -A INPUT -p tcp -m tcp --dport 21 -j ACCEPT 在其它机测试 ...
-
【NOIP2015】反思+题解
D1T1> 神奇的幻方 模拟即可. #include <cstdio> #include <cstring> #include <algorithm> #de ...
-
js面向对象-原型链
var Person = function (name) { this.name = name; } Person.prototype.say = function () { console.log( ...
-
if判断,switch语句
if ; else if; else; 判断操作: 格式示例: public class scanner { public static void main(String[] args){ int a ...
-
css3-盒模型display:-webkit-box;的使用
提到移动布局不得不提到盒模型display:-webkit-box;这个属性,在移动布局中浮动已经不在重要,相反自适应成为主要的需求,所以display:-webkit-box;变得尤为重要. box ...