三分钟理解“策略模式”——设计模式轻松掌握

实际问题:

由于超市隔三差五就要办促销活动,但每次促销活动的方式不一样,所以需要开发一个软件,营业员只要输入原价再选择活动类型后,就能计算出折扣以后的价钱。

普通人的做法:

mian(){ String input = readLine(); double price = readLine(); switch (input) case "九五折": price = price * 0.95; break; case "满100返50": if(price>=100) price = price - 50; break; case "不打折": break; println("打折后价钱:"+price); }

这样写会有几个问题:

1.若现在增加新的打折方式,就要修改这段代码,这就打破了“开放-封闭”的原则。

2.这段代码不易复用。当这个收银系统的其他地方也需要计算折后价的时候,只能将这段代码复制过去;那如果在维护中发现开发人员把“满100返50”写成了“满10000返50”,这时候就需要改两个地方,非常不便。

所以高级做法是:

1.将这一个个折扣抽象成类,这样方便代码的复用;

2.将对不同折扣的判断从客户程序中转移到被调用类中,从而降低客户程序中代码的复杂度。

高级做法的类图:

1.此时,对促销类型的判断从客户端转移到了Context类的构造函数中,从而用户程序只需要给Context的构造函数传入一个促销名称,Context类中的私有成员变量“促销子类对象”就能够获取该促销类的对象。

2.代码如上图构造之后,要获取折后价,只需要:

double price = new Context("满100返50").contextInterface(521);

策略模式和简单工厂模式的比较:

1.工厂模式中的工厂只负责生产对象,它把对象返回给客户端之后就撒手不管了;你客户端爱对对象干嘛就干嘛;

策略模式中的Context类类似于工厂模式中的Factory类,但有个本质区别:

Context类的构造函数Context(key)也有根据key创建不同的对象的功能,除此之外,Context类中还有一个函数contextInterface,能够调用策略类共有函数,从而客户端只需要一个Context类就能够完成两件事情:1.创建策略类对象、2.调用策略类对象中共有函数。因此,使用策略模式时,用户根本不需要知道策略类们的存在,用户只需要知道一个Context类和每种策略类对应的key,就能执行不同策略的功能了。

策略模式中的策略类是用前提的:

一个个策略类们必须要有一个公有接口,每一个策略类都要实现公有接口的抽象函数,从而Context中的contextInterface()函数就能够调用这个公有函数。

2.工厂模式中工厂能创建两种类型类的对象:

a)一个类它需要创建好几种对象,每种对象的属性值不一样;

b)一个类它需要创建好几种对象,每种对象都是一个父类/接口的子类;

而策略模式创建的策略类只能是第二种,而且所有子类中都必须要有共同的函数,好让Context类的contextInterface()调用。

策略模式的作用:

1.使用了策略模式后,如果需要增加一种策略,那么只需要创建一个实现了Strategy接口的子类,并重写其中的函数,然后在Context的构造函数中增加这种子类的判断。客户端的代码、Context中contextInterface()的代码无需作任何修改。

2.策略模式与简单工厂模式的相似之处:

Context的构造函数、Factory的getBean()都是用来判断创建何种类型的对象的。

工厂模式和策略模式都能够将“客户端对究竟创建何种类型的判断”转移到Factory/Context中,从而减少客户端代码的复杂度,降低服务端与客户端之间的藕合度。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏用户1191492的专栏

物联网平台设计文档:精简GC(垃圾回收)

许多高级编程语言的自动内存管理功能让编程变成了比较容易的一件事。然而,嵌入式平台经常缺少这一部分功能,这是有原因的:现代垃圾收集(GC)系统使用的...

2705
来自专栏about云

hadoop开发必读:认识Context类的作用

问题导读: 1.Context能干什么? 2.你对Context类了解多少? 3.Context在mapreduce中的作用是什么? 本文实在能够阅读源码...

3234
来自专栏阮一峰的网络日志

Javascript编程风格

Douglas Crockford是Javascript权威,Json格式就是他的发明。 去年11月他有一个演讲(Youtube),谈到了好的Javascrip...

3326
来自专栏鸿的学习笔记

合理选择数据结构

写程序很重要的一点是选择合理的数据结构,不合适的数据结构在如今高性能计算机盛行的情况下,小数据量体现不出什么来,但是在超大数据的时候, 你所面临的困境将会无穷的...

672
来自专栏進无尽的文章

如何优化冗长的条件语句

【1】尽量少用 else 尽量多用 if reture 的语法方式。 【2】字典的逻辑对应转化作用。 【3】用多态替代条件语句 【4】策略模式,继承重写,...

1391
来自专栏PHP在线

PHP程序员容易忽略的几点精华

1、变量、数组的应用技巧   (1)很多人用得不多的数组函数。foreach、list、each。分别举几个例子,应该就能知道了。例:   $dat...

35210
来自专栏量子位

干货 | 如何写一个更好的Python函数?

《Writing Idiomatic Python》一书的作者在Medium上发表了一篇文章,给出了6个建议。

812
来自专栏林德熙的博客

C# Find vs FirstOrDefault

需要知道,两个方法都是 Linq 的方法,使用之前需要引用 Linq 。对于 List 等都是继承可枚举Enumerable这时获取第一个元素可以使用First...

821
来自专栏灯塔大数据

技术 | Python从零开始系列连载(二十七)

为了解答大家学习Python时遇到各种常见问题,小灯塔特地整理了一系列从零开始的入门到熟练的系列连载,每周五准时推出,欢迎大家学积极学习转载~

1013
来自专栏程序人生 阅读快乐

C Primer Plus(第6版)(中文版)

《C Primer Plus(第6版)中文版》详细讲解了C语言的基本概念和编程技巧。

921

扫码关注云+社区