设计模式(1)--简单工厂模式、策略模式

1. 简单工厂模式

在阎宏博士的《JAVA与模式》一书中开头是这样描述简单工厂模式的:简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。


先放图再解释。下图一是从《大话设计模式》中摘出来的。问题是:用任意一种面向对象语言实现一个计算器控制台程序,要求输入两个数和运算符号,得到结果。

简单工厂模式实现的关键点有两个:

1. 继承:定义一个抽象父类“抽象产品”(Operation类),和一堆具体的子类“实际产品”(OperationAdd等子类)。抽象父类的设计是非常重要的(属性、方法)

2. 关联关系:定义一个“工厂类”,他提供生产产品的方法(图中createOperate()),然后返回一个产品(Operation类)。关联关系使一个类知道另一个类的属性和方法。

解决问题:如何实例化一个合适的对象

扩展方法:新增“产品”子类,并修改“工厂类”的创建逻辑。

使用方法:使用工厂类创建产品类,然后调用产品方法或属性。(客户端了解两个类:工厂类和产品抽象类)

优点:简单。但应用很广哦

缺点:每次还需要修改创建逻辑,如果创建逻辑挂掉,整个就挂了。 而且每次扩展都要修改“工厂类”代码,这就需要重新编译部署代码。

使用场景:负责创建的对象比较少;客户只知道传入工厂的参数,不关心对象创建逻辑。 容易违反高内聚低耦合,一般只在很简单的情况下使用。

图一. 简单工程模式类图示例

 1 class Test{
 2     public static void main( String[] args ){
 3         Operation oper;
 4         OperationFactory operFac = new OperationFactory();
 5         oper = operFac.createOperation("+");
 6         oper.setOpA(1);
 7         oper.setOpB(2);
 8         oper.getResult();
 9     }
10 }
11
12 class OperationFactory{
13     public Operation createOperation( String op ){
14         if( op == "+" )    return new OperationAdd();
15         if( op == "-" )    return new OperationMinus();
16         if( op == "*" )    return new OperationMultiply();
17         return new OperationDivide();
18     }
19 }
20
21 abstract class Operation{
22     private double opA;
23     private double opB;
24
25     public double getOpA() {
26         return opA;
27     }
28
29     public void setOpA(double opA) {
30         this.opA = opA;
31     }
32
33     public double getOpB() {
34         return opB;
35     }
36
37     public void setOpB(double opB) {
38         this.opB = opB;
39     }
40
41     public abstract double getResult();
42 }
43
44 class OperationAdd extends Operation{
45     public double getResult(){
46         return getOpA() + getOpB();
47     }
48 }
49
50 class OperationMinus extends Operation{
51     public double getResult(){
52         return getOpA() - getOpB();
53     }
54 }
55
56 class OperationMultiply extends Operation{
57     public double getResult(){
58         return getOpA() * getOpB();
59     }
60 }
61
62 class OperationDivide extends Operation{
63     public double getResult(){
64         if( getOpB() == 0 )
65             try {
66                 throw new Exception("除数不能为0");
67             } catch (Exception e) {
68             }
69         return getOpA() / getOpB();
70     }
71 }

View Code

2. 策略模式

在阎宏博士的《JAVA与模式》一书中开头是这样描述策略(Strategy)模式的:

  策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。


先放图再解释。下图二是从《大话设计模式》中摘出来的。问题实例是:做一个商场收银软件,根据客户购买商品的单价和数量,向客户收费。而商场可能做活动:打折、满减、满返之类的。

策略模式实现的关键点有两个:

1. 继承:实现某个功能需要一个“抽象算法类”(Strategy),算法可以有不同的实现,这些”具体算法类“(ConcreteStrategy)继承”抽象算法类“的通用接口。(Strategy类的接口设计是很重要的)

2. 聚合关系:对算法的使用进行封装,即提供一个算法的对外接口(Context类),Context类持有一个Strategy,把算法的使用和算法本身分开。     Context里有算法,但这个算法具体是啥,根据上下文不同,可能会是不同的算法。在什么样的情况下,配置采用哪个算法来实现,这就是Context的工作。用户只需要提供上下文给Context,然后Context就提供调用算法的接口。这个时候,Context和Strategy的关系更密切,它充当了算法与客户之间的接口,客户完全接触不到Strategy类了,但是Context完全了解Strategy。 (聚合关系中,整体和个体是“has-a”的关系,整体部分可分离。)

扩展方法:新定义一个符合Strategy接口定义的算法,在Context里重新添加这一配置(如果采用反射,则可以避免这部分代码的修改,只需新定义ConcreteStrategy就好了,这个以后会讲)

使用方法:用户向Context传递上下文,然后调用Context的算法接口方法就好了。(客户端了解一个类:Context类)----这个可能是要和简单工厂模式联合使用

优点:

(1)提供管理相关算法的协议。同类算法实现不同,但有相同的行为特征,还可以把公共代码放到父类,避免冗余。

(2)封装算法变化。

 1 class Context{
 2     Strategy str;
 3     public Context( Strategy str ){
 4         this.str = str;
 5     }
 6
 7     public void contextInterface(){
 8         str.algorithmInterface();
 9     }
10 }
11
12 public abstract class Strategy {
13     public abstract void algorithmInterface();
14 }
15
16 class ConcreteStrategyA extends Strategy{
17     public void algorithmInterface(){}
18 }
19
20 class ConcreteStrategyB extends Strategy{
21     public void algorithmInterface(){}
22 }
23
24 class ConcreteStrategyC extends Strategy{
25     public void algorithmInterface(){}
26 }

View Code

图二.策略模式类图

3. 总结

策略模式和简单工厂模式的几点不同:

  • 策略模式有两层封装。第一,把具体算法封装到Strategy:所有实现相同功能的算法继承这个类;第二, 把算法封装起来,只提供用户需要的功能:用Context把算法封装起来,Context定义用户可以使用的接口,Context确定使用哪个算法实现用户要求的具体功能。
  • 简单工厂模式有一层封装。把产品封装到Product类,并提供生产产品的方法。即没有策略模式中的第二层封装,这里用户需要完成配置产品的动作,虽然使用工厂方法,这个配置动作简单了一些,但是用户还是要执行。但是策略模式中,用户根本就不需要去了解任何配置的事情,也不需要了解算法的存在。
  • 策略模式的应用强调:相同行为不同实现的算法封装。算法和产品的不同在于,算法原本只是为了实现对象的某个行为,由于实现经常变动,因此把这种经常改变的部分提取出来,作为一个抽象类封装起来。 所以说策略模式属于对象行为模式。
  • 简单工厂模式的应用强调:相同类别产品的封装。产品关注的是一个个的对象。所以简单工厂模式属于类的创建型模式。
  • 这两种模式都不注重实现,都是在于如何组织、调用产品或算法,所以抽象出一些新的类实现这些管理功能。----设计模式有点参考管理学的东西吧。
posted on 2015-08-31 16:42 HF_Cherish 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/hf-cherish/p/4759881.html

设计模式(1)--简单工厂模式、策略模式相关推荐

  1. 【Design pattern】简单工厂过渡策略模式

    把自己当做小菜来跟学<大话设计模式>,跟着故事的思路来走 简单工厂模式:实现一个计算器代码 策略模式:商场打折代码 根据大鸟和小菜的故事,一步步的完善问题的过程!

  2. 简单工厂和策略模式结合

    商场促销活动:打折.满额返现等等 主函数对工厂模式和策略模式结合的调用: class Program     {         static void Main(string[] args)     ...

  3. 设计模式之简单工厂模式与策略模式

    目录 一.简单工厂模式 二.策略模式 三.简单工厂和策略模式的相同和不同点 四.SpringBoot中用简单工厂搭配策略模式 一.简单工厂模式 概述:定义一个工厂类,它可以根据参数的不同返回不同的实例 ...

  4. C++设计模式-使用Qt框架模拟策略模式(Strategy)商场促销

    UML图如下: 如果单使用策略模式,会出现这个问题: 客户端判断使用哪个算法! 这里可以用简单工厂与策略模式结合! 运行截图如下: 源码如下: cash.h #ifndef CASH_H #defin ...

  5. C++设计模式-使用Qt框架模拟策略模式(Strategy)+简单工厂实现商场促销

    商城促销: 1.简单工厂模式:客户端认识两个类,CashSuper与CashFactory 2.简单工厂模式 + 策略模式:客户端只要认识CashContext就可以了,更加降低耦合性 策略模式解析: ...

  6. java-抽象工厂模式+工厂方法模式+策略模式简单应用实战(登录场景)

    前言 设计模式(Design Pattern)是一套被反复使用.多数人知晓的.经过分类的.代码设计经验的总结. 使用设计模式的目的:为了代码可重用性.让代码更容易被他人理解.保证代码可靠性. 设计模式 ...

  7. php的类图怎么生成_PHP设计模式之简单工厂模式

    PHP设计模式之简单工厂模式 先从简单工厂入门,不管是面试还是被他人面试,在问到设计模式的时候,大多数人都会提到工厂模式.毫无疑问,工厂相关的几种模式在设计模式中是最出名的也是应用比较广泛的一种模式. ...

  8. C#设计模式(2)——简单工厂模式

    一.引言 这个系列也是自己对设计模式的一些学习笔记,希望对一些初学设计模式的人有所帮助的,在上一个专题中介绍了单例模式,在这个专题中继续为大家介绍一个比较容易理解的模式--简单工厂模式. 二.简单工厂 ...

  9. 工厂模式 java场景_研磨设计模式之简单工厂模式(场景问题)

    简单工厂不是一个标准的设计模式,但是它实在是太常用了,简单而又神奇,所以还是需要好好掌握的,就当是对学习设计模式的热身运动吧.为了保持一致性,我们尽量按照学习其它模式的步骤来进行学习. 1  场景问题 ...

  10. .NET设计模式(1): 简单工厂模式

    .NET设计模式(1): 简单工厂模式 最近一直在看设计模式,想把自己的学习笔记与大家分享一下,如果能帮助大家的话,我会非常高兴,同时也欢迎大家指出里面的不足.园子里其实关于此类文章已经很多了,如果d ...

最新文章

  1. 睡眠不足,记忆力还有救吗?Nature:饿着
  2. 修改注册表 为右键添加快捷命令
  3. jQuery——clone()方法
  4. Hibernate查询
  5. ffmpeg 缩放算法_图像尺寸调整算法介绍并手动实现近邻算法
  6. php 复选框组,php – 选择所有复选框
  7. MinGW 64的安装 - 官网sourceforge安装失败非翻墙解决办法
  8. 1 源码安装Zabbix agent 3.4
  9. 【转】关于python中re模块split方法的使用
  10. PacketiX ××× Server中三层交换机的路由表配置说明:
  11. 共享单车为什么这么重?
  12. 三星k3梅林没有软件中心_斐讯K3梅林软件中心版刷机包 修正WAN口 修正2.4G 自动息屏 完美混血...
  13. sxe增加服务器,sXe Injected 反作弊插件
  14. CCNA考试题库中英文翻译版及答案1
  15. 鼠标离开 表格隐藏html,excel中滚动鼠标表格隐藏怎么取消
  16. linux开启路由器功能
  17. Day621.Spring Test 常见错误 -Spring编程常见错误
  18. java类加密_Java中常用加密类型
  19. 计算机视觉—期刊|会议名称以及出版社对应大全
  20. Linux其实也是时间管理大师——掌握crontab

热门文章

  1. Linux 运维必备150 个命令,值得收藏!
  2. 2020最新版SpringMVC面试题高频精选
  3. 空间句法软件_【特训营报名】空间句法理论与实践应用(第二期更新版)丨城市数据派...
  4. iphone 抹除设备是什么意思_SMT设备有哪些,SMT是什么意思?
  5. extjs6 引入ux_关于UX以及如何摆脱UX的6种常见误解
  6. 注释标记的原则_它关系到平台如何标记操纵的媒体。 这是设计师应遵循的12条原则。
  7. 周末包邮送书和小红包中奖名单公布
  8. 隐马尔可夫模型(HMM)及Viterbi算法
  9. Windows 10系统安装JDK1.8与配置环境
  10. [项目总结]在ios中使用soundtouch库实现变声