iOS:个人浅谈工厂模式
一、什么是工厂方法?
正式的解释是:在基类中定义创建对象的一个接口,让子类决定实例化哪个类。工厂方法让一个类的实例化延迟到子类中进行。工厂方法要解决的问题是对象的创建时机,它提供了一种扩展的策略,很好地符合了开放封闭原则。工厂方法也叫做虚构造器(Virtual Constructor)。
个人的拙见是:通过工厂方法创建工厂对象,然后在工厂类中定义创建基类的子类对象的方法并通过外部传入的条件判断去创建哪一个子类对象,不过由于OC是运行时语言,所以工厂类虽然提供了创建子类对象的方法,但是在编译时期并不能确定对象类型,编译时期创建的子类对象类型是基类类型,真正的类型在运行时期由子类来确定,也即此时确定为子类类型。
二、工厂方法的实现条件?
(1)存在继承关系
(2)运用了多态的特性
三、工厂方法的优缺点?
优点:极大地优化了代码,如果需要100个子类对象,不用再一直调用alloc方法去创建,而是直接通过其工厂类的一句代码即可实现,提高了对代码的复用性。同时,也可以将大量的操作放到工厂类中去处理,业务类中只负责去调用创建需要的对象即可。
缺点:因为它的实现条件之一必须存在继承关系,所以模式中工厂类集中了所有的创建逻辑,形成一个庞大的全能类,当所有的类不是继承自同一个父类的时候扩展比较困难。
四、创建一个简单的工厂方法如下
工厂类:PersonFactory
// PersonFactory.h
//
// Created by 夏远全 on 16/12/23.
// Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved.
// #import <Foundation/Foundation.h> extern NSString *TeacherClassName;
extern NSString *StudentClassName; @class Person;
@interface PersonFactory : NSObject /**
* 定义的一个创建子类对象的接口,通过传入的类名称创建对应的子类对象
*
* @param className 类名称
* @param callBlcok 回调,返回创建的子类对象,此时接收子类对象的类型Person类型
*/
-(void)createObject:(NSString *)className compelete:(void (^)(Person *object))callBlcok; @end
// PersonFactory
//
// Created by 夏远全 on 16/12/23.
// Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved.
// #import "PersonFactory.h"
#import "Person.h"
#import "Teacher.h"
#import "Student.h" NSString *TeacherClassName = @"Teacher";
NSString *StudentClassName = @"Student"; @implementation PersonFactory -(void)createObject:(NSString *)className compelete:(void (^)(Person *object))callBlcok{ if ([className isEqualToString:NSStringFromClass([Teacher class])]) { //创建教师类对象
Teacher *teacher = [[Teacher alloc] init]; //回调
callBlcok(teacher); //教书
[teacher teachStudent];
} if ([className isEqualToString:NSStringFromClass([Student class])]) { //创建学生类的对象
Student *student = [[Student alloc] init]; //回调
callBlcok(student); //学习
[student learnKnowledge]; }
} @end
基类:Person(里面提供的方法都被子类重写)
// Person.h
//
// Created by 夏远全 on 16/12/23.
// Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved.
// #import <Foundation/Foundation.h> @interface Person : NSObject /**
* 打印类名
*/
-(void)printClassName; @end
//
// Person.m
//
// Created by 夏远全 on 16/12/23.
// Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved.
// #import "Person.h" @implementation Person -(void)printClassName{ } @end
子类教师类:Teacher(重写基类方法的同时,也可以定义属于自己的新的方法)
// Teacher.h
//
// Created by 夏远全 on 16/12/23.
// Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved.
// #import "Person.h" @interface Teacher : Person /**
* 教师的行为
*/
-(void)teachStudent;
@end
// Teacher.m
//
// Created by 夏远全 on 16/12/23.
// Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved.
// #import "Teacher.h" @implementation Teacher -(void)printClassName{ NSLog(@"%@---%@",NSStringFromClass([self class]),self);
} -(void)teachStudent{ NSLog(@"teach student");
} @end
子类学生类:Student(重写基类方法的同时,也可以定义属于自己的新的方法)
// Student.h
//
// Created by 夏远全 on 16/12/23.
// Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved.
// #import "Person.h" @interface Student : Person /**
* 学生的行为
*/
-(void)learnKnowledge; @end
// Student.m
//
// Created by 夏远全 on 16/12/23.
// Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved.
// #import "Student.h" @implementation Student -(void)printClassName{ NSLog(@"%@---%@",NSStringFromClass([self class]),self);
} -(void)learnKnowledge{ NSLog(@"learnKnowledge");
} @end
main.m演示如下:
// main.m
// PersonFactory
//
// Created by 夏远全 on 16/12/23.
// Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved.
// #import <Foundation/Foundation.h>
#import "PersonFactory.h"
#import "Person.h"
#import "Teacher.h"
#import "Student.h" int main(int argc, const char * argv[]) {
@autoreleasepool { //创建工厂对象
PersonFactory *personFactory = [[PersonFactory alloc] init]; //连续创建Person的子类教师类对象
for (int i=; i<; i++) {
[personFactory createObject:TeacherClassName compelete:^(Person *object) {
[object printClassName];
}];
} //连续创建Person的子类学生类对象
for (int i=; i<; i++) {
[personFactory createObject:StudentClassName compelete:^(Person *object) {
[object printClassName];
}];
}
}
return ;
}
打印结果:
-- ::51.235 PersonFactory[:] Teacher---<Teacher: 0x100f01660>
-- ::51.237 PersonFactory[:] teach student
-- ::51.237 PersonFactory[:] Teacher---<Teacher: 0x103800100>
-- ::51.237 PersonFactory[:] teach student
-- ::51.237 PersonFactory[:] Teacher---<Teacher: 0x100c005c0>
-- ::51.237 PersonFactory[:] teach student
-- ::51.237 PersonFactory[:] Teacher---<Teacher: 0x100c00550>
-- ::51.237 PersonFactory[:] teach student
-- ::51.237 PersonFactory[:] Teacher---<Teacher: 0x100c00180>
-- ::51.237 PersonFactory[:] teach student
-- ::51.237 PersonFactory[:] Student---<Student: 0x100a00020>
-- ::51.237 PersonFactory[:] learnKnowledge
-- ::51.237 PersonFactory[:] Student---<Student: 0x100a02880>
-- ::51.237 PersonFactory[:] learnKnowledge
-- ::51.237 PersonFactory[:] Student---<Student: 0x103900000>
-- ::51.237 PersonFactory[:] learnKnowledge
-- ::51.237 PersonFactory[:] Student---<Student: 0x103800220>
-- ::51.238 PersonFactory[:] learnKnowledge
-- ::51.238 PersonFactory[:] Student---<Student: 0x103800230>
-- ::51.238 PersonFactory[:] learnKnowledge
Program ended with exit code:
本人原创,此处是自己对知识的回炉,如果理解有误,请大家不吝赐教,对我进行斧正。
iOS:个人浅谈工厂模式的更多相关文章
- 浅谈MVVM模式和MVP模式——Vue.js向
浅谈MVVM模式和MVP模式--Vue.js向 传统前端开发的MVP模式 MVP开发模式的理解过程 首先代码分为三层: model层(数据层), presenter层(控制层/业务逻辑相关) view ...
- iOS设计模式 - (3)简单工厂模式
iOS设计模式 - (3)简单工厂模式 by Colin丶 转载请注明出处: http://blog.csdn.net/hitwhylz/article/ ...
- IOS中 浅谈iOS中MVVM的架构设计与团队协作
今天写这篇文章是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇文章的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...
- IOS之Objective-C学习 工厂模式
工厂模式在父类里声明(可实现)创建对象的一个接口,让子类决定实例化哪个类,也就是说让一个类的实例化延迟到子类中生产. 工厂模式一般用于在不同地方创建对象和项目部署依赖多个数据库的时候. 工厂模式有三种 ...
- iOS设计模式之简单工厂模式
简单工厂模式 基本理解 到底要实例化谁,将来会不会增加实例化的对象,比如计算器增加开根运算,这是很容易变化的地方,应该考虑用一个单独的类来做这个创造实例的过程,这就是工厂. 通过使用工厂模式,我们可以 ...
- iOS设计模式:简单工厂模式
1.简述 首先需要说明一下,简单工厂模式不属于23种GOF设计模式之一.它也称作静态工作方法模式,是工厂方法模式的特殊实现(也就是说工厂模式包含简单工厂模式).这里对简单工厂模式进行介绍,是为后面的工 ...
- iOS Architectures 浅谈
iOS项目打包,或者只是在项目里面调用第三方静态库抑或是自己新建一个静态库,就要无可避免的和Architectures打交道.Architectures在Targets面板的Build Setting ...
- [转]iOS之浅谈纯代码控制UIViewController视图控制器跳转界面的几种方法
参考:http://www.mamicode.com/info-detail-469709.html 一.最普通的视图控制器UIViewContoller 一个普通的视图控制器一般只有模态跳转的功能( ...
- iOS之浅谈纯代码控制UIViewController视图控制器跳转界面的几种方法
.最普通的视图控制器UIViewContoller 一个普通的视图控制器一般只有模态跳转的功能(ipad我不了解除外,这里只说iPhone),这个方法是所有视图控制器对象都可以用的,而实现这种功能,有 ...
随机推荐
- CSS常用知识点
块级元素:width宽和height高有效. 内联元素:width宽和height高无效. 1.float:该属性的值指出了对象是否及如何浮动. none:设置对象不浮动left:设置对象浮在左边ri ...
- Unity4.0的使用
最近公司用到了Unity,自己就研究了一下. 新建一个ASP.NET MVC基本项目,在NuGet上引入Unity4.0.1最新版. 因为我使用的项目为ASP.NET MVC,所以又添加一个Unity ...
- 如何在插件中添加Actor类
只要按照BlueprintFunctionLibrary的那个模板做就好了,把用编辑器生成的代码复制到插件对应的目录 之后需要注意做以下修改 1.H文件中的 GENERATED_UCLASS_BODY ...
- Oracle 取随机数
1.从表中随机取记录 select * from (select * from staff order by dbms_random.random) where rownum < 4 ...
- 《Invert》开发日志04:工具、资源和服务
这篇记录一下<Invert>用到的工具.资源和服务.秉承两个原则:一,绝不侵犯版权:二,尽量节省开支. 首先是工具.游戏引擎使用免费的Unity个人版: 编码IDE使用免费的VisualS ...
- python操作日期和时间的方法
不管何时何地,只要我们编程时遇到了跟时间有关的问题,都要想到 datetime 和 time 标准库模块,今天我们就用它内部的方法,详解python操作日期和时间的方法.1.将字符串的时间转换为时间戳 ...
- codeforces泛做..
前面说点什么.. 为了完成日常积累,傻逼呵呵的我决定来一发codeforces 挑水题 泛做.. 嗯对,就是泛做.. 主要就是把codeforces Div.1的ABCD都尝试一下吧0.0.. 挖坑0 ...
- Android 双卡双待识别
简介 Android双卡双待已经越来越普及了,解决双卡双待管理是广大手机开发人员必须得面对的问题,为实现Android平台的双卡双待操作,笔者研究了Android 应用层操作双卡双待的机制. 机制 获 ...
- 使用功能强大的插件FastReport.Net打印报表实例
我第一次使用FastReport插件做的功能是打印一个十分复杂的excel表格,有几百个字段都需要绑定数据,至少需要4个数据源,而且用到横向.竖向合并单元格. 我不是直接连接数据库,而是使用Regis ...
- java位操作总结
在计算机中所有数据都是以二进制的形式储存的. 位运算其实就是直接对在内存中的二进制数据进行操作,因此处理数据的速度非常快. 方便演示,首先写个二进制打印方法: private static void ...