工厂模式是创建型模式,它的作用是创建对象。具体来说,常见的工厂模式包括简单工厂模式,工厂方法模式和抽象工厂模式三种。

简单工厂模式(Simple Factory Pattern)

构成


工厂类

工厂类通常包含一个静态方法(类方法),由该方法根据输入类型负责创建具体的产品(对象)。

抽象产品基类(接口)

它的作用是降低客户端和具体产品之间的耦合度。而且符合了开闭原则,以后需要加入新产品线(对象),客户端调用的代码也基本无需修改。

具体产品类

真正实现业务逻辑的子类。

解决的问题:


工厂模式的核心思想在于:

  • 通过引入工厂类,使对象的创建和使用分离了。这样的好处是它们可以独立的变化,易维护和扩展。
  • 客户端依赖抽象基类(接口),而不是具体的类,降低了耦合度。

适用的场景:


  • 有一组相似的对象,需要集中统一创建时。
  • 创建对象的过程较为复杂时。
  • 对象很多,并且有扩展需求时。
  • 客户端不需要知道创建对象的过程时。
  • 客户端使用的对象存在变动的可能,或者根本不知道使用哪一个具体对象时。

举例:

主界面设置一个TextField和一个button 然后在button的点击事件中调用工厂方法进行创建不同的类的实例:

id<calculateDelegate> example1 = [SimpleFactory createCalcute:@"+"];
[example1 calculate];id<calculateDelegate> example2 = [SimpleFactory createCalcute:@"-"];
[example2 calculate];id<calculateDelegate> example3 = [SimpleFactory createCalcute:@"*"];
[example3 calculate];id<calculateDelegate> example4 = [SimpleFactory createCalcute:@"/"];
[example4 calculate];

结果:

可以看到这里创建了四个实例,但属于不同的产品类。

看一下简单工厂的实现:

+ (id)createCalcute:(NSString *)calculatetype {NSArray *calculateArray = @[@"+",@"-",@"*",@"/"];switch ([calculateArray indexOfObject:calculatetype]) {case 0:return [[MyAdd alloc]init];break;case 1:return [[MyMinus alloc]init];break;case 2:return [[MyMultiply alloc]init];break;case 3:return [[MyDivide alloc]init];}return NULL;
}

使用一个类方法createCalcute:返回不同类的实例对象。

工厂方法模式(Factory Method Pattern)

工厂方法也称为虛构造器(virtual constructor)。它适用于这种情况:一个类无法预期需要生成哪个类的对象,想让其子头来指定所生成的对象。而前面的简单工厂模式是能够明确生成哪个类对象的。

定义:


工厂模式:定义创建对象的接口,让子类决定实例化哪一个类,工厂方法使得一个类的实例化延迟到其子类。

使用场景:


下列情况会适合使用工厂模式:

  • 编译时无法准确与其要创建的对象类
  • 类想让其子类决定在运行时创建什么
  • 类有若干个辅助类为其子类,而你想将返回某个子类这一信息局部化

Cocoa Touch框架中,NSNumber就是典型的工厂方法构造。NSNumber通过类方法numberWithBool:接口实例化NSCFBoolean实例,将bool值参数传递给实例化对象。

优势:


与直接创建新的具体对象相比,使用工厂方法创建对象可算作一种最佳做法。工厂方法模式让客户程序可以要求由工厂方法创建的对象拥有一组共同的行为。所以往类层次结构中引人新的具体产品井不需要修改客户端代码,因为返回的任何具体对象的接口都跟客户端一直在用的从前的接口相同。

问题:


该模式下产品和工厂的可扩展性都增强了,但是也随之而来的是可能会出现工厂类过多的问题。一般可以和简单工厂模式结合使用。

举例:

//IChart.h
@protocol IChart <NSObject>- (void)drawing;@end
//LineChart.m
@implementation LineChart- (void)drawing {NSLog(@"LineChart drawing.");
}@end
//PieChart.m
@implementation PieChart- (void)drawing {NSLog(@"PieChart drawing.");
}@end
//Factory.h
@protocol Factory <NSObject>- (id<IChart>)createChart;@end
//LineFactory.m
@implementation LineFactory- (id<IChart>)createChart {return [[LineChart alloc] init];
}@end
//PieFactory.m
@implementation PieFactory- (id<IChart>)createChart {return [[PieChart alloc] init];
}@end

抽象工厂模式(Abstract Factory Pattern)

工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类。抽象工厂模式里每个工厂都会生产多种产品,但不同工厂生产的产品属于不同的系列。抽象工厂模式可以用来解决多产品族的问题。

解决的问题:


  • 将一个系列的产品族统一到一起创建。
  • 容易改变产品的系列

适用的场景:


需要创建一组对象,并需要切换不同的系列时。

缺点:


  • 增加新的产品种类困难,它需要修改抽象工厂的接口。
  • 代码结构比较复杂。

抽象工厂模式与工厂方法模式的区别:


工厂方法模式:

每个抽象产品派生多个具体产品类,每个抽象工厂类派生多个具体工厂类,每个具体工厂类负责一个具体产品的实例创建;

抽象工厂模式:

每个抽象产品派生多个具体产品类,每个抽象工厂派生多个具体工厂类,每个具体工厂负责多个(一系列)具体产品的实例创建。

类比解读

简单工厂:工厂可以创建同一系列的产品,产品的接口一致,但工厂就要根据参数进行判断到底创建哪种产品
卖早饭的张婆婆:可以做茶叶蛋,包子,稀饭
工厂方法:可以有多种工厂,工厂有共同的接口,一个工厂只能产生一种产品,比起简单工厂,工厂方法就不需要判断,耦合度低了不少
刘老板:只卖包子的包子铺,只卖稀饭的稀饭庄
抽象工厂:可以产生多个系列的产品,有2个维度的产品
KFC老板:可乐系列产品、汉堡系列产品,每种系列产品又分大,中,小三种。
如果这样来看应该很容易就能区分他们之间的关系了。

举例:

//MyFactory.m
@implementation MyFactory+ (instancetype)factoryWithType:(MyFactoryProductType)type {MyFactory *factory = nil;switch (type) {case MyFactoryProductTypeCar:factory = [[CarFactory alloc] init];break;case MyFactoryProductTypePickupTruck:factory = [[PickupTruckFactory alloc] init];break;default:break;}return factory;
}@end
//CarFactory.m
@implementation CarFactory- (id<CarProtocol>)creatTypeI {CarTypeI *car = [[CarTypeI alloc] init];return car;
}- (id<CarProtocol>)creatTypeII {CarTypeII *car = [[CarTypeII alloc] init];return car;
}- (id<CarProtocol>)creatTypeIII {CarTypeIII *car = [[CarTypeIII alloc] init];return car;
}@end@implementation CarTypeI- (void)carryPeople {NSLog(@"TypeI can carry 5 people");
}@end@implementation CarTypeII- (void)carryPeople {NSLog(@"TypeII can carry 4 people");
}@end@implementation CarTypeIII- (void)carryPeople {NSLog(@"TypeIII can carry 3 people");
}@end
//PickupTruckFactory.m
@implementation PickupTruckFactory- (id<PickupTruckProtocol>)creatTypeI {PickupTruckTypeI *car = [[PickupTruckTypeI alloc] init];return car;
}- (id<PickupTruckProtocol>)creatTypeII {PickupTruckTypeII *car = [[PickupTruckTypeII alloc] init];return car;
}- (id<PickupTruckProtocol>)creatTypeIII {PickupTruckTypeIII *car = [[PickupTruckTypeIII alloc] init];return car;
}@end@implementation PickupTruckTypeI- (void)carryGoods {NSLog(@"TypeI can carry 3 tons");
}@end@implementation PickupTruckTypeII- (void)carryGoods {NSLog(@"TypeII can carry 4 tons");
}@end@implementation PickupTruckTypeIII- (void)carryGoods {NSLog(@"TypeIII can carry 5 tons");
}@end
//客户端调用
MyFactory *factory = [MyFactory factoryWithType:MyFactoryProductTypeCar];
id<CarProtocol> vehicle = [factory creatTypeI];
[vehicle carryPeople];
id<CarProtocol> vehicle2 = [factory creatTypeII];
[vehicle2 carryPeople];MyFactory *factory2 = [MyFactory factoryWithType:MyFactoryProductTypePickupTruck];
id<PickupTruckProtocol> vehicle3 = [factory2 creatTypeI];
[vehicle3 carryGoods];
id<PickupTruckProtocol> vehicle4 = [factory2 creatTypeII];
[vehicle4 carryGoods];

输出:

假设抽象工厂有一种新的产品线(SUVFactory)到来的时候,只需要修改factoryWithType:,先前代码则不需要任何修改。

[iOS开发]工厂模式相关推荐

  1. iOS开发夜间模式的设置(主题切换)

    iOS开发夜间模式的设置(主题切换) 很长一段时间没有写博客了.想到自己最近刚好做了不少重构,刚好可以总结一下. 夜间模式,很多阅读类的或资讯类的App都会这个功能.以前自己也做过,现在把它抽出来封装 ...

  2. 玩转 iOS 开发:《iOS 设计模式 — 工厂模式》

    文章转至:cainrun.github.io/14718583940- 作者感言 刚忙完就给我来一场大病, 多么痛的领悟, 好不容易好点了, 可以整理整理知识点了~ 最后: 如果你有更好的建议或者对这 ...

  3. [Unity设计模式与游戏开发]工厂模式

    前言 工厂模式(Factory Design Pattern)也是游戏开发中比较常用的创建型模式,一般情况下,工厂模式分为三种更加细分的类型:简单工厂.工厂方法和抽象工厂.在GoF设计模式一书中,它将 ...

  4. iOS开发-策略模式

    策略(Strategy)模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化.策略模式是对算法的包装,是把使用算法的责任和算法本身分割开 ...

  5. iOS开发 黑暗模式

    iOS 13终于引来了暗黑模式. 每当新特性的到来,iOS开发者们既紧张又有点小兴奋,怀揣着被虐的心态,让我们来看看暗黑模式到底是个啥. 虽然这是一个设计驱动的需求,但是本着一颗虔诚(暴躁)的心,我们 ...

  6. iOS开发-模板方法模式

    模板方法模式定义一个操作中的算法的骨架,而将步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义算法的某些特定步骤.模板方法模式是由子类决定实现算法中的步骤,工厂方法由子类决定实现哪一 ...

  7. 移动开发之设计模式-工厂模式(IOSAndroid)

    资源 完全参照 工厂模式|菜鸟教程 ,但不包括IOS代码 工厂模式 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对 ...

  8. iOS开发一路走来看到,好奇,好玩,学习的知识点记录

    AutoreleasePool http://blog.sunnyxx.com/2014/10/15/behind-autorelease/ http://blog.leichunfeng.com/b ...

  9. iOS开发-简单工厂模式

    设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性.概念很长,iOS开发中最常 ...

最新文章

  1. 拷贝构造函数和赋值函数的一些知识
  2. Linux内核 题目,《Linux内核完全注释》部分习题答案
  3. 死磕Java并发:深入分析ThreadLocal
  4. Linux上的WebSphere MQ开发快速入门
  5. Timus题目中测试数据数量的计算
  6. 数据库(二)tab补全功能,使数据库支持简体中文,日志管理,备份脚本
  7. ASP.NET开发安全问题
  8. “用于无监督图像生成解耦的正交雅可比正则化”论文解读
  9. 4列变成5列 datatable_云南美食界“5巨头”,谁才是NO.1?你家乡的那道菜也在列...
  10. Splunk学习心得
  11. Web前后端:如何分离,如何解耦?
  12. java 开发微信中回调验证一直提示 解密失败处理(Java)
  13. C#利用扩展方法,不引入新的类型,实现矩阵的操作
  14. Mac Book Pro Catalina不能打开软件,提示检查为恶意软件
  15. Go 语言高性能编程
  16. keil中下载程序的擦除功能
  17. javascript设置cookie高级篇可跨域访问
  18. 第9课:利用 Headers 的 Cookie 和 User-agent 伪装自己
  19. 【MyBatis】框架-----MyBatis的基础知识以及案例分析
  20. 为什么Julia如此受欢迎?

热门文章

  1. 代码资源网整站完整代码,基于ripro9.0定制开发,含572条精品资源数据
  2. 随着“过失导致死亡的诉讼案”要求 在发生灾难性的行人伤亡事件后, 关闭“北公园中心(NorthPark Center)
  3. 【转】让我们如此享受的慢性毒药
  4. 2021年全球与中国医用丁基橡胶行业市场规模及发展前景分析
  5. C# 存储过程传参数
  6. 小明系列故事——玩转十滴水
  7. win 系统如何删除开机启动系统选择
  8. TCP/IP概述和详解--一篇就够
  9. vm 流程运行mac os_什么是“商务”流程,为什么在我的Mac上运行?
  10. Solta冲刺美股:靠热玛吉9个月赚2亿美元 林心如代言