iOS 工厂模式

简单工厂模式,工厂方法模式,抽象工厂模式都属于创建型的设计模式

简单工厂模式

首先有一个需求,客户端需要一个计算类,这个计算类有加减乘除功能,请问你怎么设计?

最简单直接写一个计算类,实现加减乘除的接口,客户端调用传参进来,给你返回结果就行了

这样设计的扩展性不高,比如以后需要再加开根号,加法做下特殊处理的等一堆需求进来后,这个计算类就会变得非常的臃肿,不满足开闭原则,对修改关闭,对扩展开放

有任何需求都需要在计算类中做修改,这样可能影响到以前的代码,所以开闭原则就是希望对修改关闭的。那如果做到对扩展开放,就是通过继承的方式

第二种做法就是抽象一个基类计算类,计算类定好虚函数,比如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是有共性的,他们都是负责去创建抽象计算机类的子类,那么有共性的类,不就可以抽象出一个基类吗,因此抽象工厂类就这样来了

抽象工厂方法

在了解抽象工厂方法之前要先说两个名词“产品族”和“产品等级结构”

产品等级结构

比如抽象类为电视机,子类就有小米电视机,海尔电视机,海信电视机等,那么这样就构成了一个产品等级结构

产品等级结构

产品族

同一个工厂生产的,位于不同产品等级结构中的一组产品,比如手机,有华为手机,小米手机,那么小米手机和小米电视机都是一个产品族

抽象工厂方法和工厂方法在代码上的实现是一致的,产品有产品的抽象类,工厂有工厂的抽象类,只不过,工厂方法是面向一个产品等级结构,也就是说工厂方法模式中的具体工厂类只生产一种产品,而抽象工厂方法的具体工厂方法中生产多种产品,比如一个小米工厂可以生产小米手机,小米电视

总结

简单工厂方法

专门创建一个类来负责创建产品类实例,通常这个产品类都是继承于同一个基类

这个工厂类包含了必要的判断逻辑,根据外部给定的参数,创建对应的产品类对象

好处就是用户在使用的时候,无需关心这个产品类是怎么被创建出来的,只需要传对应的参数,就创建对应的产品对象出来了

工厂方法模式

工厂方法模式是在简单工厂方法的基础上,对工厂方法进行了抽象,解决了简单工厂方法中的工厂类违背开闭原则的问题;这时候的工厂类就不负责创建产品对象了,而是负责定义创建产品对象的接口或者规则,让实现接口的人(子类)去负责创建产品类对象

实现了更加复杂的层次结构,更加适用于更加复杂的业务场景以及后续扩展

抽象工厂模式

当有多个产品等级结构时,就应该采用抽象工厂方法;如果只有一个产品等级结构,那么就使用工厂方法模式;如果为了快速怼业务,并且考虑到不需要太过度的去构架,那么就直接简单工厂模式

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。通常我们所说的工厂模式是指工厂方法模...
    zfylin阅读 5,092评论 0 7
  • 该文章属于刘小壮原创,转载请注明:刘小壮[https://www.jianshu.com/u/2de707c93d...
    刘小壮阅读 14,384评论 29 59
  • 设计原则: 要依赖抽象,不要依赖具体类 目录 本文的结构如下: 什么是抽象工厂模式 为什么要用该模式 模式的结构 ...
    w1992wishes阅读 4,798评论 0 6
  • 工厂模式概述 意义 问题引出在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用...
    stoneyang94阅读 3,365评论 0 0
  • 第二天一早,辛皓果然就出现在伊笙姑姑家的客厅。 伊笙下楼时,辛皓正跟姑姑李红绯女士热聊中。准确来说,是李红绯女士正...
    小小同学阅读 2,325评论 0 1