子类做具体的实现

时间:2022-06-07 03:29:46

文将继续使用这个例子, 这里要用到抽象工厂.

披萨店的需求变换

此刻披萨店在各地授权了很多连锁分店, 但是有的分店偷工减料, 使用劣质原料取代标准原料.

披萨店老板此刻就是想解决这个问题.

原料的一致性问题

首先如何保证原料的质量问题? 可以成立一个工厂出产原料, 然后把原料分发到各地的授权店.

然后还有一个原料的一致性问题, 例如纽约的番茄酱和芝加哥的番茄酱可能有点差别, 所以它们各自需要一套原料.

也就是说各地的披萨是使用不异的原料, 但是每种原料在各地可能会存在差异(差此外实现).

子类做具体的实现

这就是纽约, 芝加哥和加州各自的原料家族.

成立原料工厂

接下来就是成立原料工厂, 这些工厂将卖力为各自的家族(所在)创建原料.

首先是工厂的接口:

子类做具体的实现

然后我们要做下面这些内容:

为每个地区创建一个工厂 (实现PizzaIngredientFactory接口及其要领)

实现一些原料的类, 它们可以呗工厂使用, 此中某些原料可以跨地区共享

最后我们把上面这些整合到PizzaStore里面.

纽约的原料工厂:

子类做具体的实现

就是实现接口, 返回本地需要的原料而已.

改削Pizza抽象类:

子类做具体的实现

这里我们把Prepare()要领(筹备原料)改成抽象的了, 其它的连结不乱.

接下来需要为各地创建差别气势派头的披萨了. 此刻各地披萨店的原料都是从工厂送来的, 就不能使用劣质原料取代了.

之前使用工厂要领模式时, 我们为每个所在创建了差别气势派头的披萨, 例如 NYCheesePizza, ChicagoCheesePizza. 你可以看一下这两个类, 它们里面只有原料部分(都是同样的原料, 但是各地气势派头差别)是差此外.

所以实际上, 我们不需要为每个所在创建差别气势派头的披萨, 原料工厂将会替我们措置惩罚惩罚各地气势派头披萨原料差别这种情况.

例如奶酪披萨只需要一个类就可以:

子类做具体的实现

为了创建奶酪披萨, 在其结构函数里面传入原料工厂为它供给原料即可.

在prepare()要领里面筹备的原料都是工厂来供给的.

使用哪些地区/气势派头的原料由工厂决定, 披萨类自己并不关心, 它只需知道怎么制作披萨就行.

这样披萨类和各地区的原质料就解耦了.

综上, 就是一句话:

原料由工厂供给.

可以再看看此外一个披萨的例子:

子类做具体的实现

改削各地的披萨店

子类做具体的实现

纽约的披萨店此刻和纽约的原料工厂组合在一起, 这样它就可以产出纽约气势派头的披萨了.

在创建披萨的时候把原料工厂传进去为披萨供给原料.

到目前位置, 我们做了什么?

我们供给了一种可以为披萨供给一族原料的工厂, 这个工厂就叫做抽象工厂.

抽象工厂为创建某一家族的产品供给接口(interface), 针对这个接口编程, 就可以实现从具体出产产品的工厂解耦.

这样做就允许我们为差此外上下文使用差别实现的工厂了.

因为我们的代码是从实际产品解耦的, 我们就可以通过替换工厂来取得差别气势派头的产品了.

子类做具体的实现

梳理一下整个流程

1. 创建纽约的披萨店:

2. 下订单买披萨

3. orderPizza要领挪用创建披萨的要领:

到这, 代码都没有变革.

4.创建披萨的时候, 使用原料工厂:

5. 披萨的筹备工序里是由工厂来供给原料:

子类做具体的实现

6. 凭据其他工序加工并返回披萨.

抽象工厂界说

抽象工厂设计模式供给了一个接口, 这个接口可以创建一族相关或依赖的东西而无需指明它们具体的类.

下面是类图:

子类做具体的实现

对应披萨店的图:

子类做具体的实现

工厂要领和抽象工厂的对照

工厂要领是通过担任来实现创建东西事情的. 而抽象工厂则是通过组合的要领.

工厂要领是让子类来创建东西, 客户只需要知道抽象类, 子类做具体的实现, 解耦.

抽象工厂供给了一个可以创建一族产品的抽象类, 这个类的实现类/子类决定产品是如何产出的, 也是解耦.

抽象工厂的长处是: 可以创建一族相关的产品. 错误谬误是它的接口对照大, 如果添加产品了需要改接口.

而工厂要领只卖力出产一个产品.

抽象工厂也经常使用工厂要领来实现具体的工厂.

而工厂要领也经常使用抽象的缔造者, 它来使用子类缔造出的具体产品.

工厂要领:

子类做具体的实现

抽象工厂:

子类做具体的实现

总结

子类做具体的实现

C#/.NET Core代码实现

原料接口: