iOS 工厂方法模式
iOS工厂方法模式
什么是工厂方法模式?
工厂方法模式和简单工厂模式十分类似,大致结构是基本类似的。不同在于工厂方法模式对工厂类进行了进一步的抽象,将之前的一个工厂类抽象成了抽象工厂和工厂子类,抽象工厂定义一个创建抽象子类的接口,抽象工厂的子类实现这些接口并决定实例化哪个抽象子类。工厂子类决定着创建哪个抽象子类,外界决定着创建哪种工厂子类,抽象子类和工厂子类是一一对应的。
在工厂方法模式中,和简单工厂模式一样,对外隐藏了抽象子类的创建过程,外界只需要关心工厂类即可,负责实例化的工厂子类决定着最后的结果。
工厂方法模式主要包含四部分:
- 工厂抽象类:定义创建抽象子类的接口,通过接口返回具体的抽象子类。
- 工厂子类:继承自工厂抽象类,并重写父类的方法来创建对应的抽象子类。
- 抽象类:定义抽象子类所需的属性和方法,子类通过继承自抽象类获得这些方法。
- 抽象子类:继承自抽象类,实现具体的操作。
为什么要用工厂方法模式?
在简单工厂模式的代码中,如果我们没有使用反射机制,只是标准的简单工厂模式代码。会有一个问题,就是如果新增加其他运算功能,需要创建一个抽象子类,但是还需要修改工厂类中的代码逻辑,这种设计是不符合开放封闭原则的。开放封闭原则对于修改是关闭的,对于扩展是开放的。而且将所有的操作子类的判断和实例化都由一个工厂类完成,如果业务比较复杂会导致工厂类负担较重。
工厂方法模式将之前负责生成具体抽象子类的工厂类,抽象为工厂抽象类和工厂子类组成的一系列类。每创建一个抽象子类,就需要创建一个工厂子类,并且一一对应,由工厂子类去生成对应的抽象子类,由外界使用方来决定生成哪个工厂子类。这样在增加新的需求时,就不需要对工厂抽象类进行修改,而是对应新增的抽象子类创建对应的工厂子类即可。
业务场景
这里的业务场景还用之前简单工厂模式中提到的运算的例子,根据运算符的不同,计算两个值的结果。
UML类图
工厂方法模式
这张类图中增加了很多工厂子类,每一个抽象子类都对应着一个工厂子类。这样做的好处就是更佳灵活,每次新添加一个抽象子类,就生成一个工厂子类,对其他类没有任何影响。
简单工厂模式违背了开放封闭原则,每次添加和删除抽象子类的时候,都需要对工厂类进行操作,这样不仅对工厂类的扩展开放了,还开放了工厂类的修改,这就是违背开放封闭原则的。因为按照开放封闭原则,新增加一个需求,应该是在原有类的基础上进行扩展,而不是对原有类进行修改。这样整个模式在生成新算法类时,只是进行扩展而不对模式中原有的代码进行修改,这就是符合开放封闭原则的。
代码实现
工厂方法模式新建一个抽象子类时,选择算法的操作还是存在的,外界的灵活性依然存在,只是将原来由工厂类对抽象子类的创建,交给工厂子类去完成创建。之前增加和删除修改的是工厂类,现在是增加工厂子类,这也是开放封闭原则的一个体现。之前的简单工厂是在工厂类中创建抽象子类,工厂方法模式在工厂子类中创建抽象子类,依然封装了对象实例化的过程。
由于代码比较多,所以这里只贴出加法和减法运算的代码,其他运算代码类似。
创建运算抽象类,声明参与运算的两个属性和运算方法,下面的具体抽象子类继承自这个类。
//.h
@interface Operation : NSObject
@property (nonatomic, assign) CGFloat numberOne;
@property (nonatomic, assign) CGFloat numberTwo;
- (CGFloat)getResult;
@end
//.m
@implementation Operation
- (CGFloat)getResult {
return 0;
}
@end
//.h
@interface OperationAdd : Operation
@end
//.m
@implementation OperationAdd
- (CGFloat)getResult {
return self.numberOne + self.numberTwo;
}
@end
//.h
@interface OperationSub : Operation
@end
//.m
@implementation OperationSub
- (CGFloat)getResult {
return self.numberOne - self.numberTwo;
}
@end
抽象工厂类,定义了实例化实际运算类的方法,由子类继承并实例化不同的运算类。
//.h
@interface Factory : NSObject
+ (Operation )CreateOperation;
@end
//.m
@implementation Factory
+ (Operation )CreateOperation {
return nil;
}
@end
//.h
@interface FactoryAdd : Factory
@end
//.m
@implementation FactoryAdd
+ (Operation )CreateOperation {
return [OperationAdd new];
}
@end
//.h
@interface FactorySub : Factory
@end
//.m
@implementation FactorySub
+ (Operation )CreateOperation {
return [OperationSub new];
}
@end
外界使用时,直接实例化某个工厂子类即可,通过外界实例化某个工厂子类来选择具体的运算类。
-(void)viewDidLoad {
Operation *oper = [FactoryAdd CreateOperation];
oper.numberOne = 13;
oper.numberTwo = 24;
NSLog(@"result : %f", [oper getResult]);
}
当需求发生改变时,需要进行算法的切换,外界只需要将工厂子类调用类方法的类名换一下即可,其他地方都不用发生变化。这样做就像一个“开关”一样,在外界由这个工厂子类的类型控制着抽象子类的实例化类型,而我们并不知道抽象子类实例化的过程。
工厂方法模式的优缺点
优点
工厂方法模式的的优点在于更大的灵活性,增加或删除某种运算都不会对其他地方造成影响,更佳符合开放封闭原则。
而且对抽象的使用更佳深入,将工厂类也抽象为了抽象工厂类和工厂子类,外界调用更加灵活,这也是对多态的一种体现。
缺点
工厂方法模式的缺点也是非常显而易见的,工厂方法模式中新增一个抽象子类,意味着工厂子类要跟着成对增加,这样会造成生成过多的类,工厂方法模式的复杂度也会随之增加。
对于这个缺点,反射机制当然可以很好的解决这个问题,工厂设计模式和反射机制的配合,可以使这种设计模式更佳易用和灵活,减少了条件判断和类的数量。
答疑解惑
使用工厂方法模式,看上去会感觉到这不是更麻烦了吗,直接在外界创建具体的抽象子类不行吗?还用这么麻烦的创建工厂子类,然后再用工厂子类去创建抽象子类。
我将从两方面回答这个问题:
假设现在项目比较大,在外界很多地方都直接使用了抽象子类直接进行运算,这种方式在写代码的时候确实很快也很爽。但是,假设有一天,产品经理过来说要改需求,我现在不要加减乘除这四种运算了,我要换成更高级的其他运算。。。如果这样改起来改动就大了,需要把所有直接使用抽象子类实例化的地方都做修改。
这只是一种设计模式的思路,在程序的开发中没有一种设计模式是万能的,在适合的地方用适合的设计模式,或根据业务需求自己制定一套模式,这才是最好的。只有最适合业务的模式,才是最好的模式。
iOS 工厂方法模式的更多相关文章
- IOS设计模式浅析之工厂方法模式(Factory Method)
概述 在软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口. 如何隔离出这个易变对象的变化,使得系统中“其它依赖该对象的对 ...
- iOS设计模式之工厂方法模式
工厂方法模式 基本理解 工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 简单工厂的最大优点就是工厂类中包含了必要的逻辑判断,根据客户端的选择 ...
- iOS常用设计模式——工厂方法(简单工厂模式,工厂方法模式, 抽象工厂模式)
1. 简单工厂模式 如何理解简单工厂,工厂方法, 抽象工厂三种设计模式? 简单工厂方法包含:父类拥有共同基础接口,具体子类实现子类特殊功能,工厂类根据参数区分创建不同子类实例.该场景对应的UML图如下 ...
- iOS经常使用设计模式——工厂方法(简单工厂模式,工厂方法模式, 抽象工厂模式)
1. 简单工厂模式 怎样理解简单工厂,工厂方法. 抽象工厂三种设计模式? 简单工厂的生活场景.卖早点的小摊贩.他给你提供包子,馒头,地沟油烙的煎饼等,小贩是一个工厂.它生产包子,馒头,地沟油烙的煎饼. ...
- 工厂方法模式——创建型模式02
1. 简单工厂模式 在介绍工厂方法模式之前,先介绍一下简单工厂模式.虽然简单工厂模式不属于GoF 23种设计模式,但通常将它作为学习其他工厂模式的入门,并且在实际开发中使用的也较为频繁. (1 ...
- 设计模式C#合集--工厂方法模式
简单工厂,代码: public interface ISpeak { public void Say(); } public class Hello : ISpeak { public void Sa ...
- PHP设计模式(二)工厂方法模式(Factory Method For PHP)
简单工厂简述: 简单工厂模式实现了生产产品类的代码跟客户端代码分离,在工厂类中你可以添加需要生成长跑的逻辑代码(new 产品类),但是问题来了,优秀的代码是符合"开闭原则"如果你要 ...
- javascript设计模式-工厂方法模式
工厂方法模式笔记 通过对产品类的抽象使其创建业务主要负责用于创建多类产品的实例 对于创建多类对象,简单工厂不太实用,这是简单工厂模式的应用局限,当然这正是工厂方法模式的价值之所在 通过工厂方法模 ...
- C#设计模式(3)——工厂方法模式
一.概念:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类. 二.代码实现 namespace 设计模式之工厂方法模式 { /// <summary&g ...
随机推荐
- android 中targetSdkVersion和与target属性的区别
AndroidMenifest.xml中targetSdkVersion和project.properties中的target属性的区别 在AndroidMenifest.xml中,常常会有 ...
- windows下mysql开启远程访问权限
1.mysql -u root -p 2.use mysql 3.GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '密码' WITH G ...
- Angular开发Tips
1.在使用$routeProvider的时候,需要让模块依赖ngRoute,否则会提示找不到服务,示例: angular.module('module1', ['ngRoute']) .config( ...
- Tip8:Unity中诸如 Awake() Start() Update()等函数的 执行顺序
Unity脚本中有很多的事件函数,下面是各种函数的执行顺序: 1.reset(); 2.Awake(); 3.OnEnable; 4.OnLevelWasLoaded(); 5.Start(); 6. ...
- 剑指架构师系列-tomcat6通过IO复用实现connector
由于tomcat6的配置文件如下: <Connector port="80" protocol="org.apache.coyote.http11.Http11Ni ...
- 使用 CSS3 打造一组质感细腻丝滑的按钮
CSS3 引入了众多供功能强大的新特性,让设计和开发人员能够轻松的创作出各种精美的界面效果.下面这些发出闪亮光泽的按钮,很漂亮吧?把鼠标悬停在按钮上,还有动感的光泽移动效果. 温馨提示:为保证最佳的效 ...
- C++ 多态的实现原理与内存模型
多态在C++中是一个重要的概念,通过虚函数机制实现了在程序运行时根据调用对象来判断具体调用哪一个函数. 具体来说就是:父类类别的指针(或者引用)指向其子类的实例,然后通过父类的指针(或者引用)调用实际 ...
- SQL Server里强制参数化的痛苦
几天前,我写了篇SQL Server里简单参数化的痛苦.今天我想继续这个话题,谈下SQL Server里强制参数化(Forced Parameterization). 强制参数化(Forced Par ...
- Python文件操作详解
Python内置了一个open()方法,用于对本地文件进行读写操作.这个功能简单.实用,属于必须掌握的基础知识. 使用open方法操作文件可以分三步走,一是打开文件,二是操作文件,三是关闭文件.下面分 ...
- ref和out 传递参数(C#)
1.参数传递默认都是传递栈空间里面存储的内容 2.如果添加了ref那么传递的都是栈空间地址,而不再是栈空间里面的内容 3.如果添加了out,那么传递的也是栈空间的地址 //写一个方法计算一个int类型 ...