iOS设计模式(03):工厂方法
2019独角兽企业重金招聘Python工程师标准>>>
GOF是这样描述工厂模式的:
“Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.”
在基类中定义创建对象的一个接口,让子类决定实例化哪个类。工厂方法让一个类的实例化延迟到子类中进行。
工厂方法要解决的问题是对象的创建时机,它提供了一种扩展的策略,很好地符合了开放封闭原则。工厂方法也叫做虚构造器(Virtual Constructor)。
如下图所示,是工厂方法的类结构图:
什么时候使用工厂方法?
当是如下情况是,可以使用工厂方法:一个类不知道它所必须创建的对象的类时,一个类希望有它的子类决定所创建的对象时。
更多关于工厂方法的介绍,可以参考本文最后给出的参考内容。下面我们就来看看在iOS中工厂方法的一种实现方法。
iOS中工厂方法的实现
如下有一个类图,该图描述了下面即将实现的工厂方法(利用工厂方法,创建出不同的形状)。其中BVShapeFactory为工厂方法的基类,BVShape为形状的基类,BVClient通过BVShapeFactory,利用 BVShapeFactory的子类(BVCircleShapeFactory和BVSquareShapeFactory)分别创建出BVCircleShape和BVSquareShape。
如下图,是在Xcode中创建的相关文件
(具体实现步骤如下(建议下载本文最后给出的代码实例,用Xcode查阅代码):
1.创建一个形状基类BVShape。该类中定义了形状的基本行为和属性,如下代码所示:
BVShape.h
1.//
2.// BVShape.h
3.// FactoryMethodPattern
4.//
5.// Created by BeyondVincent on 13-5-15.
6.// Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.
9.#define BV_Exception_Format @"在%@的子类中必须override:%@方法"
10.
11.@interface BVShape : NSObject
12.
13.@property (nonatomic, weak)NSString *name;
14.
15.// 子类必须重写这个draw方法,否则会抛出异常错误
16.-(void)draw;
17.
18.@end
BVShape.m
1.//
2.// BVShape.m
3.// FactoryMethodPattern
4.//
5.// Created by BeyondVincent on 13-5-15.
6.// Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.
9.#import "BVShape.h"
10.
11.@implementation BVShape
12.
13.-(id)init
14.{
15. self = [super init];
16. if (self) {
17. // 做一些初始化任务
18. }
19. return self;
20.}
21.
22.-(void)draw
23.{
24. // 如果是通过BVShape的实例调用此处的draw,则绘制一个BVShape图形
25. if ([self isMemberOfClass:[BVShape class]]) {
26. NSLog(@"绘制一个BVShape图形");
27. } else {
28. // 如果是通过BVShape子类的实例调用了此处的draw,则抛出一个异常:表明子类并没有重写draw方法。
29. // 注:在OC中并没有abstract class的概念,只有protocol,如果在基类中只定义接口(没有具体方法的实现),
30. // 则可以使用protocol,这样会更方便。
31. [NSException raise:NSInternalInconsistencyException
32. format:BV_Exception_Format, [NSString stringWithUTF8String:object_getClassName(self)], NSStringFromSelector(_cmd)];
33. }
34.}
35.
36.@end
在上面的代码中定义了一个draw方法,为了让子类必须实现该方法,在BVShape中做了特殊处理,具体内容可以看上面的代码,已经有注视了。
2.子类化形状基类。首先子类化一个圆形类:BVCircleShape。
BVCircleShape.h
1.//
2.// BVCircleShape.h
3.// FactoryMethodPattern
4.//
5.// Created by BeyondVincent on 13-5-15.
6.// Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.
9.#import "BVShape.h"
10.
11.@interface BVCircleShape : BVShape
12.
13.@end
BVCircleShape.m
1.//
2.// BVCircleShape.m
3.// FactoryMethodPattern
4.//
5.// Created by BeyondVincent on 13-5-15.
6.// Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.
9.#import "BVCircleShape.h"
10.
11.@implementation BVCircleShape
12.
13.-(void)draw
14.{
15. NSLog(@"绘制一个BVCircleShape图形");
16.}
17.
18.@end
在上面的子类中,重写了基类的draw方法。同样,我们再子类化一个正方形类,并重写draw方法,如下代码所示:
BVSquareShape.h
1.//
2.// BVSquareShape.h
3.// FactoryMethodPattern
4.//
5.// Created by BeyondVincent on 13-5-15.
6.// Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.
9.#import "BVShape.h"
10.
11.@interface BVSquareShape : BVShape
12.
13.@end
BVSquareShape.m
1.//
2.// BVSquareShape.m
3.// FactoryMethodPattern
4.//
5.// Created by BeyondVincent on 13-5-15.
6.// Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.
9.#import "BVSquareShape.h"
10.
11.@implementation BVSquareShape
12.
13.-(void)draw
14.{
15. NSLog(@"绘制一个BVSquareShape图形");
16.}
17.
18.@end
3.创建一个工厂方法的基类BVShapeFactory
BVShapeFactory.h
1.//
2.// BVShapeFactory.h
3.// FactoryMethodPattern
4.//
5.// Created by BeyondVincent on 13-5-15.
6.// Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.
9.#import "BVShape.h"
10.
11.@interface BVShapeFactory : NSObject
12.
13.-(BVShape *) factoryMethod;
14.
15.@end
BVShapeFactory.m
1.//
2.// BVShapeFactory.m
3.// FactoryMethodPattern
4.//
5.// Created by BeyondVincent on 13-5-15.
6.// Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.
9.#import "BVShapeFactory.h"
10.
11.@implementation BVShapeFactory
12.
13.-(BVShape *)factoryMethod
14.{
15. // 在此处,子类必须重写factoryMethod方法。当然,在工厂模式中,也可以在此处返回一个默认的Product。
16. // 如果是通过BVShapeFactory子类的实例调用了此处的factoryMethod,则抛出一个异常:表明子类并没有重写factoryMethod方法。
17. [NSException raise:NSInternalInconsistencyException
18. format:BV_Exception_Format, [NSString stringWithUTF8String:object_getClassName(self)], NSStringFromSelector(_cmd)];
19.
20. // 下面这个return语句只是为了消除警告,实际上永远都不会执行到这里。
21. return nil;
22.}
23.
24.@end
在上面的代码中,定义了一个factoryMethod,该类的子类必须实现该方法,通过实现该方法,返回一个具体的形状对象。下面来看看该类的子类化。
4.子类化工厂方法的基类。首先子类化一个圆形工厂方法BVCircleShapeFactory:
BVCircleShapeFactory.h
1.//
2.// BVCircleShapeFactory.h
3.// FactoryMethodPattern
4.//
5.// Created by BeyondVincent on 13-5-15.
6.// Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.
9.#import "BVShapeFactory.h"
10.#import "BVCircleShape.h"
11.
12.@interface BVCircleShapeFactory : BVShapeFactory
13.
14.@end
BVCircleShapeFactory.m
1.//
2.// BVCircleShapeFactory.m
3.// FactoryMethodPattern
4.//
5.// Created by BeyondVincent on 13-5-15.
6.// Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.
9.#import "BVCircleShapeFactory.h"
10.
11.@implementation BVCircleShapeFactory
12.
13.-(BVShape *)factoryMethod
14.{
15. return [[BVCircleShape alloc] init];
16.}
17.
18.@end
如上代码所示,重写了factoryMethod,返回一个BVCircleShape实例。下面来看看另外一个子类BVSquareShapeFactory:
BVSquareShapeFactory.h
1.//
2.// BVSquareShapeFactory.h
3.// FactoryMethodPattern
4.//
5.// Created by BeyondVincent on 13-5-15.
6.// Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.
9.#import "BVShapeFactory.h"
10.#import "BVSquareShape.h"
11.
12.@interface BVSquareShapeFactory : BVShapeFactory
13.
14.@end
BVSquareShapeFactory.m
1.//
2.// BVSquareShapeFactory.m
3.// FactoryMethodPattern
4.//
5.// Created by BeyondVincent on 13-5-15.
6.// Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.
9.#import "BVSquareShapeFactory.h"
10.
11.@implementation BVSquareShapeFactory
12.
13.-(BVShape *)factoryMethod
14.{
15. return [[BVSquareShape alloc] init];
16.}
17.
18.@end
该子类返回的是一个BVSquareShape实例。
5.工厂方法的使用。定义一个BVClient类,在该类中演示工厂方法的使用。代码如下:
BVClient.h
1.//
2.// BVClient.h
3.// FactoryMethodPattern
4.//
5.// Created by BeyondVincent on 13-5-15.
6.// Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.
9.@interface BVClient : NSObject
10.
11.-(void)doSomething;
12.
13.@end
BVClient.m
1.//
2.// BVClient.m
3.// FactoryMethodPattern
4.//
5.// Created by BeyondVincent on 13-5-15.
6.// Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.
9.#import "BVClient.h"
10.
11.#import "BVShapeFactory.h"
12.#import "BVCircleShapeFactory.h"
13.#import "BVSquareShapeFactory.h"
14.
15.#import "BVShape.h"
16.#import "BVCircleShape.h"
17.#import "BVSquareShape.h"
18.
19.@implementation BVClient
20.
21.-(void)doSomething
22.{
23. // 工厂方法的实例化
24. BVShapeFactory *circleShapefactory = [[BVCircleShapeFactory alloc] init];
25. BVShapeFactory *squareShapefactory = [[BVSquareShapeFactory alloc] init];
26.
27. // 通过工厂方法实例化对应的形状
28. BVShape *circleShape = [circleShapefactory factoryMethod];
29. BVShape *squareShape = [squareShapefactory factoryMethod];
30.
31. // 调用形状的方法
32. [circleShape draw];
33. [squareShape draw];
34.}
35.
36.@end
如上代码所示,首先实例化两个工厂方法,并通过工厂方法创建出对应的形状,最后调用形状的draw方法进行测试。会在控制台窗口输出如下内容:
2013-05-16 10:12:46.292 FactoryMethodPattern[2845:c07] 绘制一个BVCircleShape图形
2013-05-16 10:12:46.295 FactoryMethodPattern[2845:c07] 绘制一个BVSquareShape图形
转载于:https://my.oschina.net/u/1432769/blog/375410
iOS设计模式(03):工厂方法相关推荐
- python类是实例的工厂_Python设计模式之工厂方法模式实例详解
本文实例讲述了Python设计模式之工厂方法模式.分享给大家供大家参考,具体如下: 工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定实例化哪一个类, ...
- 设计模式复习-工厂方法模式
设计模式复习-工厂方法模式 相对于简单工厂,工厂方法是把算法类的实例化延迟到了调用者那去做,调用者根据自己的需要,自己实例化相关的工厂并且生产相关算法.这么做是因为简单工厂是不满足OCP的,因为如果 ...
- C#设计模式(3)——工厂方法模式
一.引言 在简单工厂模式中讲到简单工厂模式的缺点,有一点是--简单工厂模式系统难以扩展,一旦添加新产品就不得不修改简单工厂方法,这样就会造成简单工厂的实现逻辑过于复杂,然而本专题介绍的工厂方法模式可以 ...
- 设计模式之工厂方法模式(创建型)
一.模式定义 工厂方法模式:又称工厂模式,也叫虚拟构造器模式,属于构建型设计模式,工厂方法模式是在简单工厂模式上进行拓展,生产产品的过程由具体工厂类实现,基类只实现接口,这使得工厂方法模式可以在不修改 ...
- 设计模式之工厂方法模式应用例题
设计模式之工厂方法模式应用例题 题目描述 类结构图及相关说明 程序代码 运行结果 题目描述 现需要设计一个程序来读取多种不同类型的图片格式,针对每一种图片格式都设计一个图片读取器(ImageReade ...
- 设计模式:工厂方法模式(Factory method)
设计模式:工厂方法模式(Factory method) 一.问题 在前一章中通过披萨的实例介绍了简单工厂模式.在披萨实例中,如果我想根据地域的不同生产出不同口味的披萨,如纽约口味披萨,芝加哥口味披萨. ...
- 【设计模式】工厂方法模式(C#)
[设计模式]工厂方法模式 1.概述 针对简单工厂中的缺点,使用工厂方法模式就可以完美的解决,完全遵循开闭原则. 定义一个用于创建对象的接口,让子类决定实例化哪个产品类对象.工厂方法使一个产品类的实例化 ...
- 二、java设计模式之工厂方法+抽象工厂模式(创建型设计模式)
创建型设计模式-工厂模式和应用 工厂模式介绍: 它提供了一种创建对象的最佳方式,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象 例子: 需要购买一辆车,不用管 ...
- 一文叫你弄懂Java设计模式之工厂方法模式:图解+日志记录器代码实例
文章目录 详解Java设计模式之工厂方法模式 案例引入工厂方法模式 工厂方法模式 定义 案例分析 UML类图分析 代码分析 工厂方法的重载 工厂方法的隐藏 模式优点 模式缺点 模式适用环境 详解Jav ...
最新文章
- mysql的or能去重吗_mysql条件查询中AND与OR联合使用的注意事项!
- python绘制一个圆_Python在网格上绘制一个填充的“圆”
- javascript技术教程蔡敏_程序员都必掌握的前端教程之JavaScript基础教程(上)
- !Important:CSS中!important的作用用于Ie6.0 与Ie7.0、firefox
- python 的笔记
- 《python cookbook》chapter 1
- Theano 中文文档 0.9 - 7.2.4 条件
- Python中list,tuple,dict,set的区别和用法
- 中等职业技术学校计算机课件,中等职业技术学校计算机教学论文
- 湖北校园天翼飞young使用路由器上网
- Vue经典开源项目汇总
- matlab信号处理——数据处理基础
- git FETCH_HEAD 版本回滚 ORIG_HEAD
- javascript Date format(js日期格式化)
- 区块链研究实验室-首次提出如何确保区块链分片技术的数据完整性
- 软件体系结构的基本概念与作用
- 最小编辑距离 (MED)实现-Python
- java poi jar包下载_poi.jar下载-poi.jar包下载 (3.8/3.9/3.10)版--pc6下载站
- js 中文转拼音缩写
- Protobuf是什么?
热门文章
- mysql完整字段包括_MySQL字段类型最全解析
- windows编程一日一练(2)
- 怎么用计算机算亩数,怎样用手机测量亩数?
- python 九宫重排_[蓝桥杯][历届试题]九宫重排 (Python代码)(bfs+集合)
- 帆软日期控件变灰_FineReport-JS脚本常见日期使用整理
- weiler-atherton多边形裁剪算法_EAST算法超详细源码解析:数据预处理与标签生成...
- 一次ajax多次回调结果,Ajax异步的回调函数执行了多遍
- queue源码java_看看AbstractQueue源码Java9
- bat判断文本中是否存在一个相同内容比较_Excel中的9个逻辑函数都不掌握,还敢称Excel达人?...
- rust(10)-函数指针