设计模式——简单工厂,工厂方法,抽象工厂
2016-04-13 23:31
585 查看
简书地址:http://www.jianshu.com/p/a4e7ee099fd2
创建型模式(5):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式(7):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式(11):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
本身设计模式的诞生,也是基于设计模式的六大原则:
单一职责原则(Single Responsibility Principle)
里氏替换原则(Liskov Substitution Principle)
依赖倒置原则(Dependence Inversion Principle)
接口隔离原则(Interface Segregation Principle)
迪米特法则(Law Of Demeter)
开闭原则(Open Close Principle)
具体这六大原则的含义,可以参考设计模式六大原则。
我自己在用设计模式的过程当中,主要感觉到其实设计模式有以下作用:
更方便模块的复用和测试
方便看懂和修改另一个写的代码!
本文主要以代码形式实现每一种设计模式,算是自己的一种复习和实践。相应的代码,也会放到github上。
工厂方法
抽象工厂
《Head First》的例子:
客户到pizza store点不同类型的pizza,有cheese的,也有clam的。
pizza类:
Simple Factory:
Pizza Store:
何时使用:
* 编译时无法准备预期要创建的对象的类
* 类想让其子类决定在运行时创建什么
* 类有若干辅助类为子类,而你想将返回哪个子类这一信息局部化
《Head First》的例子:
纽约和芝加哥的pizza store有各自差异化的风味,提供当地风格的cheese和clam的pizza。
pizza类:
pizza store抽象:
pizza store实现:
何时使用:
* 系统需要屏蔽有关对象如何创建,如何组织和如何表达
* 系统需要由关联的多个对象来构成
* 有关联的多个对象需要一起应用并且它们的约束是强迫的(不可分离)。
* 你想提供一组对象而不显示它们的实现过程,只显示它们的接口。
抽象工厂和工厂方法的区别:
抽象工厂:
* 通过对象组合创建抽象产品
* 创建多系列产品
* 必须修改父类的接口才能支持新的产品
工厂方法:
* 通过类继承创建抽象产品
* 创建一种产品
* 子类化创建者并重载工厂方法以创建新的产品
《Head First》的例子:
纽约和芝加哥的pizza store提供的cheese和clam的pizza,但原料不同,做出来的pizza也不同。
原料类:
pizza类:
pizza 子类:
pizza ingredient factory 抽象
pizza ingredient factory 实现
pizza store抽象:
pizza store实现:
为了不再需要直接创建对象,降低代码耦合度。对于创建多种具有同一系列行为的物体,使用工厂方法。对于产品族使用抽象工厂。
2.简单工厂的缺点
简单工厂主要违反了开闭原则:对扩展开放,对修改关闭。添加一种对象,就要去修改简单工厂中的获取对象方法。
2.《Head First设计模式》
3.设计模式六大原则
4.[设计模式六大原则](/article/5098634.html)
前言
设计模式在工作中经常会用到:创建型模式(5):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式(7):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式(11):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
本身设计模式的诞生,也是基于设计模式的六大原则:
单一职责原则(Single Responsibility Principle)
里氏替换原则(Liskov Substitution Principle)
依赖倒置原则(Dependence Inversion Principle)
接口隔离原则(Interface Segregation Principle)
迪米特法则(Law Of Demeter)
开闭原则(Open Close Principle)
具体这六大原则的含义,可以参考设计模式六大原则。
我自己在用设计模式的过程当中,主要感觉到其实设计模式有以下作用:
更方便模块的复用和测试
方便看懂和修改另一个写的代码!
本文主要以代码形式实现每一种设计模式,算是自己的一种复习和实践。相应的代码,也会放到github上。
本篇主要讲:
简单工厂工厂方法
抽象工厂
0.简单工厂
简单工厂本身并不是23种设计模式的一种,更比较像一种编程习惯,但也是经常使用。《Head First》的例子:
客户到pizza store点不同类型的pizza,有cheese的,也有clam的。
pizza类:
#import <Foundation/Foundation.h> typedef NS_ENUM(NSInteger, PizzaType){ Cheese = 0, Clam = 1 }; @interface SFPizza : NSObject - (void) prepare; - (void) bake; - (void) cut; - (void) box; @end
#import "SFPizza.h" @interface SFCheesePizza : SFPizza @end @interface SFClamPizza : SFPizza @end
Simple Factory:
#import <Foundation/Foundation.h> #import "SFPizza.h" @interface SFPizzaSimpleFactory : NSObject - (SFPizza *) createPizza:(PizzaType) pizzaType; @end
#import "SFPizzaSimpleFactory.h" #import "SFCheesePizza.h" #import "SFClamPizza.h" @implementation SFPizzaSimpleFactory - (SFPizza *) createPizza:(PizzaType) pizzaType{ SFPizza *pizza = nil; if (pizzaType == Cheese){ pizza = [[SFCheesePizza alloc]init]; }else if (pizzaType == Clam){ pizza = [[SFClamPizza alloc]init]; } return pizza; } @end
Pizza Store:
#import <Foundation/Foundation.h> #import "SFPizza.h" @interface SFPizzaStore : NSObject - (SFPizza *) orderPizza:(PizzaType)pizzaType; @end
#import "SFPizzaStore.h" #import "SFPizzaSimpleFactory.h" @interface SFPizzaStore(){ SFPizzaSimpleFactory *_simpleFactory; } @end @implementation SFPizzaStore - (instancetype)init{ self = [super init]; if ( self ){ _simpleFactory = [[SFPizzaSimpleFactory alloc]init]; } return self; } - (SFPizza *) orderPizza:(PizzaType)pizzaType{ SFPizza *pizza = [_simpleFactory createPizza:pizzaType]; [pizza prepare]; [pizza bake]; [pizza cut]; [pizza box]; return pizza; } @end
1.工厂方法
概念:定义创建对象的接口,让子类决定实例化哪一个类。工厂方法使得一个类的实例化延迟到子类。何时使用:
* 编译时无法准备预期要创建的对象的类
* 类想让其子类决定在运行时创建什么
* 类有若干辅助类为子类,而你想将返回哪个子类这一信息局部化
《Head First》的例子:
纽约和芝加哥的pizza store有各自差异化的风味,提供当地风格的cheese和clam的pizza。
pizza类:
#import <Foundation/Foundation.h> typedef NS_ENUM(NSInteger, PizzaType){ Cheese = 0, Clam = 1 }; @interface FMPizza : NSObject - (void) prepare; - (void) bake; - (void) cut; - (void) box; @end
#import "FMPizza.h" @interface FMNYCheesePizza : FMPizza @end @interface FMNYClamPizza : FMPizza @end @interface FMChicagoCheesePizza : FMPizza @end @interface FMChicagoClamPizza : FMPizza @end
pizza store抽象:
#import <Foundation/Foundation.h> #import "FMPizza.h" @protocol FMPizzaStore <NSObject> - (FMPizza *) createPizza:(PizzaType)pizzaType; - (FMPizza *) orderPizza:(PizzaType)pizzaType; @end
pizza store实现:
#import <Foundation/Foundation.h> #import "FMPizzaStore.h" @interface FMNYPizzaStore : NSObject<FMPizzaStore> @end
#import "FMNYPizzaStore.h" #import "FMNYCheesePizza.h" #import "FMNYClamPizza.h" @implementation FMNYPizzaStore - (FMPizza *) createPizza:(PizzaType)pizzaType{ FMPizza *pizza = nil; if (pizzaType == Cheese){ pizza = [[FMNYCheesePizza alloc]init]; } else if (pizzaType == Clam){ pizza = [[FMNYClamPizza alloc]init]; } return pizza; } - (FMPizza *) orderPizza:(PizzaType)pizzaType{ FMPizza *pizza = [self createPizza:pizzaType]; [pizza prepare]; [pizza bake]; [pizza cut]; [pizza box]; return pizza; } @end
#import <Foundation/Foundation.h> #import "FMPizzaStore.h" @interface FMChicagoPizzaStore : NSObject<FMPizzaStore> @end
#import "FMChicagoPizzaStore.h" #import "FMChicagoCheesePizza.h" #import "FMChicagoClamPizza.h" @implementation FMChicagoPizzaStore - (FMPizza *) createPizza:(PizzaType)pizzaType{ FMPizza *pizza = nil; if (pizzaType == Cheese){ pizza = [[FMChicagoCheesePizza alloc]init]; } else if (pizzaType == Clam){ pizza = [[FMChicagoClamPizza alloc]init]; } return pizza; } - (FMPizza *) orderPizza:(PizzaType)pizzaType{ FMPizza *pizza = [self createPizza:pizzaType]; [pizza prepare]; [pizza bake]; [pizza cut]; [pizza box]; return pizza; } @end
2.抽象工厂
概念:提供一个创建一系列相关或相互以来对象的接口,而无需指定它们的具体的类。何时使用:
* 系统需要屏蔽有关对象如何创建,如何组织和如何表达
* 系统需要由关联的多个对象来构成
* 有关联的多个对象需要一起应用并且它们的约束是强迫的(不可分离)。
* 你想提供一组对象而不显示它们的实现过程,只显示它们的接口。
抽象工厂和工厂方法的区别:
抽象工厂:
* 通过对象组合创建抽象产品
* 创建多系列产品
* 必须修改父类的接口才能支持新的产品
工厂方法:
* 通过类继承创建抽象产品
* 创建一种产品
* 子类化创建者并重载工厂方法以创建新的产品
《Head First》的例子:
纽约和芝加哥的pizza store提供的cheese和clam的pizza,但原料不同,做出来的pizza也不同。
原料类:
@interface AFCheese : NSObject @end @interface AFNYCheese : AFCheese @end @interface AFChicagoCheese : AFCheese @end @interface AFClam : NSObject @end @interface AFNYClam : AFClam @end @interface AFChicagoClam : AFClam @end @interface AFSauce : NSObject @end
pizza类:
#import <Foundation/Foundation.h> #import "AFCheese.h" #import "AFClam.h" #import "AFSauce.h" #import "AFPizzaIngredientFactory.h" typedef NS_ENUM(NSInteger, PizzaType){ Cheese = 0, Clam = 1 }; @interface AFPizza : NSObject @property (nonatomic, strong) AFCheese *cheese; @property (nonatomic, strong) AFClam *clam; @property (nonatomic, strong) AFSauce *sauce; - (instancetype)initWithPizzaIngredientFactory:(id<AFPizzaIngredientFactory>) factory; - (void) prepare; - (void) bake; - (void) cut; - (void) box; @end
#import "AFPizza.h" @implementation AFPizza - (instancetype)initWithPizzaIngredientFactory:(id<AFPizzaIngredientFactory>) factory{ self = [super init]; return self; } - (void) prepare{ } - (void) bake{ NSLog(@"start bake"); } - (void) cut{ NSLog(@"start cut"); } - (void) box{ NSLog(@"start box"); } @end
pizza 子类:
#import "AFPizza.h" @interface AFCheesePizza : AFPizza @end #import "AFCheesePizza.h" @interface AFCheesePizza(){ id<AFPizzaIngredientFactory> _factory; } @end @implementation AFCheesePizza - (instancetype)initWithPizzaIngredientFactory:(id<AFPizzaIngredientFactory>) factory{ self = [super init]; if (self){ _factory = factory; } return self; } - (void)prepare{ self.cheese = [_factory createCheese]; self.sauce = [_factory createSource]; } @end
#import "AFPizza.h" @interface AFClamPizza : AFPizza @end #import "AFClamPizza.h" @interface AFClamPizza(){ id<AFPizzaIngredientFactory> _factory; } @end @implementation AFClamPizza - (instancetype)initWithPizzaIngredientFactory:(id<AFPizzaIngredientFactory>) factory{ self = [super init]; if (self){ _factory = factory; } return self; } - (void)prepare{ self.clam = [_factory createClam]; self.sauce = [_factory createSource]; } @end
pizza ingredient factory 抽象
#import <Foundation/Foundation.h> @class AFCheese; @class AFClam; @class AFSauce; @protocol AFPizzaIngredientFactory - (AFCheese *) createCheese; - (AFClam *) createClam; - (AFSauce *) createSource; @end
pizza ingredient factory 实现
#import <Foundation/Foundation.h> #import "AFPizzaIngredientFactory.h" @interface AFNYPizzaIngredientFactory : NSObject<AFPizzaIngredientFactory> @end #import "AFNYPizzaIngredientFactory.h" #import "AFNYCheese.h" #import "AFNYClam.h" #import "AFSauce.h" @implementation AFNYPizzaIngredientFactory - (AFCheese *) createCheese{ return [[AFNYCheese alloc]init]; } - (AFClam *) createClam{ return [[AFNYClam alloc]init]; } - (AFSauce *) createSource{ return [[AFSauce alloc]init]; } @end
#import <Foundation/Foundation.h> #import "AFPizzaIngredientFactory.h" @interface AFChicagoIngredientFactory : NSObject<AFPizzaIngredientFactory> @end #import "AFChicagoIngredientFactory.h" #import "AFChicagoCheese.h" #import "AFChicagoClam.h" #import "AFSauce.h" @implementation AFChicagoIngredientFactory - (AFCheese *) createCheese{ return [[AFChicagoCheese alloc]init]; } - (AFClam *) createClam{ return [[AFChicagoClam alloc]init]; } - (AFSauce *) createSource{ return [[AFSauce alloc]init]; } @end
pizza store抽象:
#import <Foundation/Foundation.h> #import "AFPizza.h" @protocol AFPizzaStore - (AFPizza *) createPizza:(PizzaType)pizzaType; - (AFPizza *) orderPizza:(PizzaType)pizzaType; @end
pizza store实现:
#import <Foundation/Foundation.h> #import "AFPizzaStore.h" @interface AFNYPizzaStore : NSObject<AFPizzaStore> @end #import "AFNYPizzaStore.h" #import "AFNYPizzaIngredientFactory.h" #import "AFCheesePizza.h" #import "AFClamPizza.h" @implementation AFNYPizzaStore - (AFPizza *) createPizza:(PizzaType)pizzaType{ AFPizza *pizza = nil; AFNYPizzaIngredientFactory *factory = [[AFNYPizzaIngredientFactory alloc]init]; if ( pizzaType == Cheese ){ pizza = [[AFCheesePizza alloc]initWithPizzaIngredientFactory:factory]; }else if ( pizzaType == Clam ){ pizza = [[AFClamPizza alloc]initWithPizzaIngredientFactory:factory]; } return pizza; } - (AFPizza *) orderPizza:(PizzaType)pizzaType{ AFPizza *pizza = [self createPizza:pizzaType]; [pizza prepare]; [pizza bake]; [pizza cut]; [pizza box]; return pizza; } @end
#import <Foundation/Foundation.h> #import "AFPizzaStore.h" @interface AFChicagoPizzaStore : NSObject<AFPizzaStore> @end #import "AFChicagoPizzaStore.h" #import "AFChicagoIngredientFactory.h" #import "AFCheesePizza.h" #import "AFClamPizza.h" @implementation AFChicagoPizzaStore - (AFPizza *) createPizza:(PizzaType)pizzaType{ AFPizza *pizza = nil; AFChicagoIngredientFactory *factory = [[AFChicagoIngredientFactory alloc]init]; if ( pizzaType == Cheese ){ pizza = [[AFCheesePizza alloc]initWithPizzaIngredientFactory:factory]; }else if ( pizzaType == Clam ){ pizza = [[AFClamPizza alloc]initWithPizzaIngredientFactory:factory]; } return pizza; } - (AFPizza *) orderPizza:(PizzaType)pizzaType{ AFPizza *pizza = [self createPizza:pizzaType]; [pizza prepare]; [pizza bake]; [pizza cut]; [pizza box]; return pizza; } @end
一些个人总结
1.什么时候会去用工厂模式?(简单工厂,工厂方法,抽象工厂)为了不再需要直接创建对象,降低代码耦合度。对于创建多种具有同一系列行为的物体,使用工厂方法。对于产品族使用抽象工厂。
2.简单工厂的缺点
简单工厂主要违反了开闭原则:对扩展开放,对修改关闭。添加一种对象,就要去修改简单工厂中的获取对象方法。
参考资料
1.《Objective-C编程之道 iOS设计模式解析》2.《Head First设计模式》
3.设计模式六大原则
4.[设计模式六大原则](/article/5098634.html)
相关文章推荐
- 探索子线程autorelease对象的释放时机
- 异步时间扭曲
- App测试
- 集群监控之 —— ipmi操作指南
- Node.js 命令行程序开发教程
- 简单监测iOS卡顿的demo
- ASUS RT-N16 DD-WRT ipkg update
- org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: sys.entity.Role; nested exception is org.hibernate.PersistentObjectException: 的解决方案
- 系统盘(c盘)空间清理方法总结(转)
- yii2使用多个数据库的案例
- Java多线程(一)
- 张孝祥整理的一些面试题(EJB/BEAN/WEBSERVICE)
- 腾讯2016春季校园实习招聘技术岗复试(二面)问题汇总(CC++后台)
- 腾讯2016春季校园实习招聘技术岗复试(二面)问题汇总(CC++后台)
- iOS使用Category添加@property变量
- iOS crash分析
- C++中重定义、重写、重载的区别以及隐藏与覆盖的访问
- android 从相册中获取图片
- HYSBZ 2565 最长双回文串
- iOS实现无限后台background的方法