架构算法设计模式和编程理论

工厂模式

2019-06-02  本文已影响2人  Corbin___

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

简单工厂模式

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

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

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

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

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

抽象工厂方法

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

产品等级结构

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

产品等级结构

产品族

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

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

总结

简单工厂方法

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

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

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

工厂方法模式

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

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

抽象工厂模式

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

上一篇下一篇

猜你喜欢

热点阅读