Head_First设计模式(三)----工厂模式抽象工厂

配图来源网络

简述设计模式

本篇博文将继续介绍工厂模式中的抽象工厂

如果感觉不太好接受可以先看上一篇 Head_First设计模式(三)—-工厂模式简单工厂

抽象工厂相关知识点和思路

涉及到的知识点

主要包括: 基类, 继承的使用(对应部分会在代码中详细标注)。
工厂模式可以划分为: 简单工厂和抽象工厂两类。

思路分析

新的需求: 当我们依据我们的简单工厂对我们的Pizza经营有成, 这导致现在大家都想加盟我们。新的问题又来了每个加盟点都会根据自己的地域风格对Pizza进行轻微修改。

我们已经有的一个比较麻烦的做法, 为每一个加盟店建立一个工厂。虽然可以达到目的, 但并不是我们想要的。如果使用这样的方式我们的代码将出现大量的重复工作

而我们需要的是更多一些的质量控制

我们把这个例子划分为两部分产品类(pizza) 和创建者(pizzastore)

步骤分析

  • 我们为Pizza指定使用的框架, 让加盟店制作Pizza的活动局限于Pizza店超类, 又有自己区域的风味

  • 我们要把制作披萨的方法 creatPizza 放到PizzaStore中 设置成私有方法

  • 各地加盟店继承Pizza店超类。重写覆盖父类中的creatPizza方法

  • 最后使用统一的披萨订单系统

这样既节省了代码数量, 有提高了代码质量, 最主要的是层次不一样了。

实现步骤

创建创造者类, PizzaStore超类, 以及他的两个子类(加盟店)NYPizzaStore, ChigPizzaStore

创建产品类Pizza子类(地域风味Pizza), NYMeatPizza, NYVegetablePizza, ChigMeatPizza, ChigVegetablePizza

PizzaStore超类
/* 订单方法外部调用 */

+ (Pizza *)orderPizza:(NSString *)type;
+ (Pizza *)orderPizza:(NSString *)type {

   Pizza *pizza = [self createPizza:type]; /* 私有方法 */

   [self babk:pizza];

   [self cut:pizza];

   [self box:pizza];

   return pizza;

}
/* 默认情况就会制作正厂的pizza */
+ (Pizza *)createPizza:(NSString *)type {

   Pizza *pizza = [PizzaFactory creatPizzaWith:type]; /* 使用工厂 */

   return pizza;

}

其他地域比如纽约店(NYPizzaStore)

我们会在NYPizzaStore中重写父类的createPizza方法, 根据自己的风格去调试


+ (Pizza *)createPizza:(NSString *)type {

    Pizza *pizza;

    if ([type isEqualToString:@"NYGreek"]) {

        pizza = [[NYGreekPizza alloc] init];

    } else {

        pizza = [[NYVegetablesPizza alloc] init];

    }

    return pizza;
}

这样我们就可以完美的解决我们的需求

抽象工厂: 所有的工厂都是对对象创建的过程进行封装, 它将对象实例的时间推到了子类中去实现, 抽象工厂让我们的子类去重写父类中创建对象的方法来实现自己的地域风格。

扩展

如果你不喜欢下面这样的判断格式我还有一个好办法推荐

/* 这里只有两个分支看上去还好, 如果种类多了看上去就很麻烦 */
if ([type isEqualToString:@"NYGreek"]) {

        pizza = [[NYGreekPizza alloc] init];

    } else {

        pizza = [[NYVegetablesPizza alloc] init];

    }

这里我推荐这个方法写在工厂里


+ (Pizza *)creatPizzaWith:(NSString *)type {

    Pizza *pizza =  [[NSClassFromString(type1) alloc] init];/* 通过传入的名字创建类来实例对象 */

    return pizza;

}

使用的时候我们传入需要的Pizza类名字符串字作为type即可

/* 我们可以直接传入类的名字比如NYVegetablePizza */
Pizza *pizza = [NYPizzaStore orderPizza:@"NYVegetablePizza"];

工厂模式在ios中比较常用到的地方, 就是在创建tableview的cell, 也就是我们常说的cell工厂。网上很多demo随便可以找到

好处: 我们这样封装起创建对象的代码, 就可以进行抽象编码, 将客户的代码和真实的实现解耦, 虽然在我们的代码中不可避免的还是需要去实例, 但是我们把这些创建对象的代码圈在了自己可约束的范围内, 不会出现让人束手无策的情况

让我们来看一下如果不适用工厂去实现我们的Pizza店例子简单的图如下

一个很依赖的Pizza店, 我们的高层组件PizzaStore完全依赖下面的底层组件

一个很依赖的Pizza店

这样的逻辑感觉就像抛弃了我们的OO设计理念, 我们的PizzaStore依赖于所有类型的Pizza, 各类Pizza的任何改变都会对PizzaStore造成影响。

说到这里我们不得不提到一个新的关键词语依赖倒置原则, 我们要依赖抽象, 不要去依赖具体类。 这也是对我们工厂模式最好的阐述。

而我们的工厂模式应用之后我们的PizzaStore看起来会是这个样子

工厂模型

这里我们不难看出无论是我们的PizzaStore 和各种Pizza 都依赖于我们的抽象Pizza, 这样就遵循了我们的依赖倒置原则。

虽然想要遵循依赖倒置原则的方式并不唯一, 但是工厂确实最容易理解和威力最大的技巧之一。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值