优惠券的工厂与策略模式实现方案

?? 优质资源分享 ??

学习路线指引(点击解锁) 知识定位 人群定位
?? Python实战微信订餐小程序 ?? 进阶级 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
??Python量化交易实战?? 入门级 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统

真正开发中使用最频繁的模式基本就是【策略】和【工厂】这个两个模式。

按照”国际惯例”先引入些模式的概念和示例。(示例参考Head First,但是力求比它讲的简洁且清晰)

之后在详细讲解优惠券的设计和模式应用。

所有面向对象入门的时候都是以人、动物为示例。讲解什么是【继承】等相关概念。这个是符合直觉的。

但是在实际应用中,继承用到的地方有限,它有它的问题,它是一种【强耦合】方式,一般使用【策略模式】【装饰模式】代替继承。

以鸭子动物设计为例,讲解继承方式存在哪些问题:

优惠券的工厂与策略模式实现方案

有些功能很好界定,有些功能很“尴尬”,例如fly功能。

fly不能加在超类上,因为不是所有鸭子都有fly功能。

如果加在超类上就导致所有的子类都要实现或者继承这个可能不适用的方法。

而且也不是所有鸭子都会quack(例如木头玩具鸭子),那些没有quack的鸭子,同样要实现或继承quack。

想利用继承来达到代码复用的目的有以下问题:

  1. 同样的display功能代码在子类中重复,代码没有【复用】。
  2. 这些子类鸭子的display、fly代码是写死的,想运行时候修改很难。
  3. 由于每个display功能分散在不同的子类鸭子中,很难知道全部的行为。
  4. 我们修改了父类会导致牵一发而动全身。所有鸭子都受到了影响。同时我们修改某个相同类型display行为的时候,需要每个鸭子去找该相同代码进行修改。

设计升级:

优惠券的工厂与策略模式实现方案

我们以一个人的一天活动为例子。

讲完【面向接口编程】,我们继续讲如何完善鸭子示例。替代继承的方式就是【组合】,多用组合,少用继承。“有一个”比“是一个”更好,每一个鸭子都有一个FlyBehavior和一个QuackBehavior,好将飞行和咕咕叫委托给他们处理。鸭子的行为不是继承来的,而是和“适当”的对象“组合”而来。组合的好处:

1.将一类行为封装成类2.运行时动态改变行为。

优惠券的工厂与策略模式实现方案 优惠券的工厂与策略模式实现方案

Duck

优惠券的工厂与策略模式实现方案

Bduck

优惠券的工厂与策略模式实现方案

Test

总结:

策略模式:定义算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

解释:示例中鸭子的飞行就有不同的策略,有的用翅膀飞,有的用火箭飞。

不同的人对于“滚”这个指令也有自己不同的应对策略,有的是跑,有的是上前揍你。

而这些策略是可以【复用】和【统一管理】的。我们通过【组合】的方式,将策略“放入”到类中,运行时可以更换不同策略。

而不是通过继承来获得这个行为。组合比继承更加灵活,和方便。

但是策略模式还留下了一个问题就是,如何“放入”这个策略对象到类中,如果是new对象的形式,这个就和new的那个策略绑定死了。

我们希望的是,在程序运行过程中,通过输入参数的不同,动态组合不同的实现类。从而实现不同的行为。

例如:我们通过优惠券的类型字段获取不同的优惠券实现类。有的是满减,有的是折扣,但是程序不关心这些类型。

他只要将价格计算委托到不同的策略上计算出最终价格即可。

简单工厂模式:

工厂的职责就是新建产品。

以下单匹萨为例。pizza接口定义了pizza的制作方法。不同种类的pizza负责各自的实现,不同pizza有的烤的时间长,有的切的块小。

以下是典型的面向接口编程,甚至还有点策略模式的味道。

| |

|

唯一的问题是,如果我pizza的种类有了增删,我需要修改if-else这块代码。这个就违反了【开闭原则】

我们应该将变化的地方【隔离变化】。

简单工厂:

优惠券的工厂与策略模式实现方案

|

|

simplePizzaFactory就干一件事,就是新建比萨。

对于需要单例的我们可以选用单例模式:

优惠券的工厂与策略模式实现方案

单例实现模式
工厂封装的好处:

  1. 可能很多地方都需要新建pizza对象。如果有pizza种类增删或改变,我们只需要修改simplePizzaFactory这一个地方。【避免多处修改】,有时新建对象没一行代码那么简单,比如连接池这种对象,集中管理很重要。
  2. createPizza方法可以是static的。好处是不需要实例化对象就可以使用,缺点是不能通过继承来改变创建方法的行为。
  3. 工厂模式让我们实现了【依赖倒置】,以前虽然已经面向接口编程,但是我们始终要new出具体实现类,一旦new出了具体实现类,虽然是面向接口编程,但是相当于和具体实现绑定死了,运行时无法改变的。有了工厂,我们高层组建现在只依赖接口或者抽象类,底层实现类也是依赖接口或者抽象类。不依赖具体的实现类。具体实现类可以运行时通过传参由工厂动态产生。

工厂封装的缺点:

  1. 如果有pizza种类增删或改变,虽然只要修改一处,避免了多处修改。但是还是要修改简单工厂的if-else,还是有违【开闭原则】。

为了遵守【开闭原则】,有两种方式:升级简单工厂、工厂方法模式。

升级简单工厂:

工厂也可以是一个接口或者抽象类,我们工厂也可能有很多种实现方式。

我们先实现了一种AStyleSimplePizzaFactory,如果后续需求变更,pizza种类有添加,我们可以在新建一个BStyleSimplePizzaFactory。

你可以认为这是一种分类方式。例如在中国,豆腐脑厂家。南方和北方都是生产豆腐脑,但是一个甜口一个咸口。

| pizza店可以按照风味分类:

| 交通工具也可以通过类型分类:
|
| 其实你也可以不按照这个分类。就是简单工厂,里面通过if-else判断,建造不同风味的pizza也没问题。同样,你也可以把交通工具不按照“海陆空”方式分类。我就在简单工厂中,返回不同类型的交通工具实例。完全没毛病。
but,但是。。。。按照项目进程,我们不能预测后续要添加多少需求,我们只能按照已知先写了一个版本,真的后续添加了产品或者逻辑,我们不修改以前的代码。我们只能新加工厂和实现类。就是为了符合【开闭原则】你可以认为一期只有AStyleSimplePizzaFactory,随着项目迭代,各种B、C工厂都出来了。
个人以为:大部分项目开始完全没有必要使用这么复杂的简单工厂,【简单软件有简单软件的设计】,后续迭代去修改工厂类,或者有需求之后慢慢演进到这种升级版的简单工厂才是正途。
老法师都是想着简洁高效,新手才想着一定要高级有逼格。 |

交通工具工厂 |

工厂方法模式:

|
 
  |


优惠券的工厂与策略模式实现方案

来源:xuhss_com

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年5月9日
下一篇 2022年5月9日

相关推荐