简单工厂模式,工厂方法模式,抽象工厂模式都属于创建型的设计模式
简单工厂模式
首先有一个需求,客户端需要一个计算类,这个计算类有加减乘除功能,请问你怎么设计?
最简单直接写一个计算类,实现加减乘除的接口,客户端调用传参进来,给你返回结果就行了
这样设计的扩展性不高,比如以后需要再加开根号,加法做下特殊处理的等一堆需求进来后,这个计算类就会变得非常的臃肿,不满足开闭原则,对修改关闭,对扩展开放
有任何需求都需要在计算类中做修改,这样可能影响到以前的代码,所以开闭原则就是希望对修改关闭的。那如果做到对扩展开放,就是通过继承的方式
第二种做法就是抽象一个基类计算类,计算类定好虚函数,比如result函数等,创建加减乘除四个子类,都实现result方法,这样有利于以后的扩展,比如需要开根号计算,就再创建一个开根号子类,实现result方法,这样不会修改原本的代码,但是将功能扩展出来了
客户端调用
Add *add = [[Add alloc] init];
[add result];
Sub *sub = [[Sub alloc] init];
[sub result];
Multi *multi = [[Multi alloc] init];
[multi result];
Division *division = [[Division alloc] init];
[division result];
以后如果再添加其他算法,客户端都得认识这种算法类,客户端得写对应的子类,对于这种方式,我们可以采用简单工厂模式,将子类的创建代码,放到工厂类中,外部调用只需要告诉工厂类需要创建什么对象
工厂类
/// 工厂类
@interface Factory : NSObject
+ (instancetype)creatWithType:(NSString *)type;
@end
@implementation Factory
+ (instancetype)creatWithType:(NSString *)type
{
switch (type) {
case @"+":
return [[Add alloc] init];
break;
case @"-":
return [[Sub alloc] init];
break;
case @"*":
return [[Multi alloc] init];
break;
case @"/":
return [[Division alloc] init];
break;
default:
return nil;
break;
}
}
@end
抽象计算类
@interface AbstractProduct : NSObject
- (CGFloat)result;
@end
@implementation AbstractProduct
- (CGFloat)result
{
}
@end
客户端调用
AbstractProduct *p = [Factory creatWithType:@"+"];
[p result];
那么这样做的好处就是将代码的职责分离,工厂类负责创建对象,计算子类负责对应的需求,客户端只需要通过工厂就可以拿到想要的子类,然后通过抽象基类调虚函数,就能获取对应的结果
但是这样还是违背了开闭原则,比如我添加一个开根号类,这时候工厂类中的if-else或switch需要对应的添加代码,这样日积夜累,工厂类会变得臃肿,再对其做修改后,影响面很大
工厂方法模式
工厂方法模式可以解决简单工厂方法模式违背开闭原则
刚才我们解决计算类违背开闭原则的,就是通过计算类定义虚函数,子类实现虚函数,外部调用result方法就可以了,如果添加开根号类,一样创建子类,实现result,这样就不会修改原来的代码了
一样的方法,原本的工厂类违背开闭原则了,那么我们创建一个抽象工厂类,定义creat虚函数,加减乘除四个工厂子类实现creat函数
客户端调用
Add *add = [FactoryAdd creat];
Sub *sub = [FactorySub creat];
在客户端调用上,似乎抽象工厂类没有作用,因为创建产品的还是子工厂类来创建,那么我为什么还要继承抽象工厂类?
当然,我们可以不用继承抽象工厂类,比如FactoryAdd和FactorySub继承NSObject,定义creat方法,返回对应的产品对象,在客户端的调用,依旧跟上段代码一样,效果也一样
那么当我们这样做后,是不是发现其实FactoryAdd和FactorySub是有共性的,他们都是负责去创建抽象计算机类的子类,那么有共性的类,不就可以抽象出一个基类吗,因此抽象工厂类就这样来了
抽象工厂方法
在了解抽象工厂方法之前要先说两个名词“产品族”和“产品等级结构”
产品等级结构
产品等级结构比如抽象类为电视机,子类就有小米电视机,海尔电视机,海信电视机等,那么这样就构成了一个产品等级结构
产品族
同一个工厂生产的,位于不同产品等级结构中的一组产品,比如手机,有华为手机,小米手机,那么小米手机和小米电视机都是一个产品族
抽象工厂方法和工厂方法在代码上的实现是一致的,产品有产品的抽象类,工厂有工厂的抽象类,只不过,工厂方法是面向一个产品等级结构,也就是说工厂方法模式中的具体工厂类只生产一种产品,而抽象工厂方法的具体工厂方法中生产多种产品,比如一个小米工厂可以生产小米手机,小米电视
总结
简单工厂方法
专门创建一个类来负责创建产品类实例,通常这个产品类都是继承于同一个基类
这个工厂类包含了必要的判断逻辑,根据外部给定的参数,创建对应的产品类对象
好处就是用户在使用的时候,无需关心这个产品类是怎么被创建出来的,只需要传对应的参数,就创建对应的产品对象出来了
工厂方法模式
工厂方法模式是在简单工厂方法的基础上,对工厂方法进行了抽象,解决了简单工厂方法中的工厂类违背开闭原则的问题;这时候的工厂类就不负责创建产品对象了,而是负责定义创建产品对象的接口或者规则,让实现接口的人(子类)去负责创建产品类对象
实现了更加复杂的层次结构,更加适用于更加复杂的业务场景以及后续扩展
抽象工厂模式
当有多个产品等级结构时,就应该采用抽象工厂方法;如果只有一个产品等级结构,那么就使用工厂方法模式;如果为了快速怼业务,并且考虑到不需要太过度的去构架,那么就直接简单工厂模式
网友评论