简单工厂模式、工厂方法模式、抽象工程模式 【OC】

1,038 阅读5分钟

举例说明:

收购前-简单工厂模式:

        故事如下,一哥们外号叫大金链子,大金链子从小受父母的影响,特别有经商头脑,有一次,大金链子去了一地,看当前的一家做衣服的小店,生意特别火爆,开始的时候,小店只生产裤子,小店秉诚着童叟无欺的经商理念,获得了远近商家的好评,因而生意一天比一天好,因而后续也做各种各样的衣服,但是大金链子一看,生意好是好,但是规模还是太小只是在这个小镇而已,因而大金链子就想着收购这家做衣服的小店,这个小店的老板是一对年纪稍大的老夫妻,由于年纪大了也不想这么忙了,于是就转让给了大金链子。

        大金链子接手了这家店之后,感觉这家店名声还是不错的,于是以这家店的经营理念不断的去扩张,刚开始的时候小店的经营范围只在当地,做衣服做裤子什么的都可以的,这个时候可以称之为简单工厂。

收购后-工厂方法:

          但是大金链子做了整合之后,由于销售的范围在多个县城,这个时候的小店的产量就跟不上了,于是大金链子将这个小店的经营拆分成多个单品类的工厂,比如衣服工厂,裤子工厂等等,他向各个县城的商户提供这个单品类的衣服。商户需要什么衣服就到相应的工厂去订购,这个时候的各品类的工厂就是工厂方法(有好几大单品类的工厂)。

改革后-抽象工厂:

         随着时间的推移,小店的名气也越来越大,由于小店各个品类的衣服需求量不同,造成了不同程度的浪费,因而小店进行了改革,进军高端成衣市场,这个时候小店向外提供的时候只能是成衣,因而大金链子提出了一个新型的工厂(设计部门-设计高端衣服),这个工厂用来管理其他单品类的工厂,将其他单品类的工厂的衣服进行组合,形成高端的潮流衣服。这个时候的设计部就可以称之为抽象工厂,而且之后商家要买衣服就要到他这个设计部进行订购。

工厂方法模式和抽象工厂模式的区别?
1、工厂方法和抽象工厂的任务都是负责实例化对象,但是工厂方法用的方式是继承,而抽象工厂方式用的方法是对象组合。
2、工厂方法注重于:把对象实例化的代码从具体类中解耦出来 —— 通过子类继承实现,或者目前还不知道将来需要实例化哪些具体类时;抽象工厂注重于:当你需要创建产品家族和想让制造的相关产品集中起来时。

在介绍工厂模式之前,先说一下OC并没有提供抽象类(abstract class),所以如果我们需要的话需要自己实现一下,其实就是把init重写,如果直接调用本类的init 返回nil。

- (instancetype)init
{
    if ([self isMemberOfClass:YiFu.class]) { /** 这里一定要用 isMemberOfClass, 区分开isKindOfClass */
        [self doesNotRecognizeSelector:_cmd];
        return nil;
    }
    self = [super init];
    if (self) {
        
    }
    return self;
}

简单工厂

直接用代码示意

我们去买衣服 ,有毛衣 和 卫衣两种

  1. 创建一个协议 YiFuProtocol

    @protocol YiFuProtocol (NSString *)name; @end

2.创建 MaoYi 和 WeiYi 类 遵守YiFuProtocol协议

@interface WeiYi : NSObject <YiFuProtocol>
 
@end
@implementation WeiYi
- (NSString *)name {
    return @"WeiYi L";
}
@end
 
@interface MaoYi : NSObject <YiFuProtocol>
 
@end
@implementation MaoYi
- (NSString *)name {
    return @"MaoYi L";
}
@end

3.创建工厂类

@interface YiFuFactory : NSObject
 
+ (id<YiFuProtocol>)yifuWithType:(NSString *)type;
 
@end
 
@implementation YiFuFactory
 
+ (id<YiFuProtocol>)yifuWithType:(NSString *)type {
    if ([type isEqualToString:@"毛衣"]) {
        return [[MaoYi alloc] init];
    }else if ([type isEqualToString:@"卫衣"]) {
        return [[WeiYi alloc] init];
    }
    return nil;
}
 
@end

4.调用

    id<YiFuProtocol> obj = [YiFuFactory yifuWithType:@"毛衣"];

2.工厂方法模式

  1. 创建工厂抽象类

  2.  @protocol YiFuMakeProtocol <NSObject>
     - (id<YiFuProtocol>)createYiFu;
     @end
    
  3. 创建工厂实体

  4.  // 毛衣的工厂类
     @interface MaoYiFactory : NSObject <YiFuMakeProtocol>
     @end
      
     @implementation MaoYiFactory
     - (id<YiFuProtocol>)createYiFu {
         return [[MaoYi alloc] init];
     }
     @end
     // 卫衣的工厂类
     @interface WeiYiFactory : NSObject <YiFuMakeProtocol>
     @end
      
     @implementation WeiYiFactory
     - (id<YiFuProtocol>)createYiFu {
         return [[WeiYi alloc] init];
     }
     @end
     
     
    
  5. 产品抽象类 还是之前的 毛衣和卫衣也是之前的

  6.  @interface WeiYi : NSObject <YiFuProtocol>
      
     @end
     @implementation WeiYi
     - (NSString *)name {
         return @"WeiYi L";
     }
     @end
      
     @interface MaoYi : NSObject <YiFuProtocol>
      
     @end
     @implementation MaoYi
     - (NSString *)name {
         return @"MaoYi L";
     }
     @end
     
     
    
  7. 客户端调用

    id factory = [[MaoYiFactory alloc] init];

    id yifu = [factory createYiFu];

    NSLog(@"size : %@",[yifu name] );

3.抽象工厂模式

现在客户要买 衣服 和 裤子

首先提供一个协议 创建衣服和裤子,现在有两个工厂 A厂 生产毛衣、毛裤, B厂 生产卫衣,卫裤。

之前已经有了衣服的协议,我们再来一个裤子的协议,为了不和衣服协议重复,假设为材料吧

@protocol KuZiMakeProtocol <NSObject>
- (NSString *)cailiao;
@end

创建两个产品类 毛裤 卫裤

@interface MaoKu : NSObject <KuZiProtocol>
@end
@implementation MaoKu
- (NSString *)cailiao {
    return @"maoku C";
}
@end
 
@interface WeiKu : NSObject <KuZiProtocol>
@end
@implementation WeiKu
- (NSString *)cailiao {
    return @"weiku  C";
}
@end

工厂抽象类

@protocol ShopProtocol <NSObject>
- (id<YiFuProtocol>)createYiFu;
- (id<KuZiProtocol>)createKuZi;
@end

A、B工厂

@interface A : NSObject <ShopProtocol>
@end
@implementation A
- (id<YiFuProtocol>)createYiFu {
    return [[MaoYi alloc] init];
}
- (id<KuZiProtocol>)createKuZi {
    return [[MaoKu alloc] init];
}
@end
 
@interface B : NSObject <ShopProtocol>
@end
@implementation B
- (id<KuZiProtocol>)createKuZi {
    return [[WeiKu alloc] init];
}
- (id<YiFuProtocol>)createYiFu {
    return [[WeiYi alloc] init];
}
@end

客户端调用

  id<ShopProtocol> shop  = [[A alloc] init];    
id<YiFuProtocol> yifu = [shop createYiFu];    
id<KuZiProtocol> kuzi = [shop createKuZi];

4.总结

简单工厂

优势:可以根据不同条件创建不同的对象,区分了责任和权限,可以优化项目结构 劣势:所有实例创建都聚集在了一起

 工厂方法

 核心工厂类不再负责具体产品创建,将工作分发给子类,自己只提供子类必须实现的接口。 在本例中是用的protocol ,更好的方式应该是抽象类,可以提供默认实现,子类需要的话重写就可以。 用户在使用产品的时候只需要关心接口提供的方法即可。

抽象工厂

 该模式是指有多个抽象角色时所使用的工厂模式。定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。