抽象工厂模式
介绍
抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据里氏替换原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。
定义
为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
模拟场景
我们还是继续假设这个人喜欢唱歌,唱歌需要麦克风,音响等等设备。但是具体用哪个牌子的麦克风或者音响,要看个人喜爱和当天的心情。
我们把这个场景进行划分:
抽象工厂:个人当天需要的设备
具体工厂:当天用的到底是哪个品牌的麦克风和音响
抽象产品:肯定就是麦克风或者音响了
具体产品:就是具体的牌子的麦克风或者音响
抽象工厂的UML 图
image代码片段
产品audio
@protocol <NSObject>
audio-(void)audio;
@end
import "audio.h"
@interface AudioA : NSObject<audio>
@end
import "AudioA.h"
@implementation AudioA
-(void)audio{
NSLog(@"audioA audio");
}
@end
import "audio.h"
@interface AudioB : NSObject<audio>
@end
import "AudioB.h"
@implementation AudioB
-(void)audio{
NSLog(@"audioB audio");
}
@end
产品Microphone
@protocol Microphone<NSObject>
-(void)song;
@end
import "Microphone.h"
@interface MicrophoneA : NSObject<Microphone>
@end
import "MicrophoneA.h"
@implementation MicrophoneA
-(void)song{
NSLog(@"microphoneA song");
}
@end
import "Microphone.h"
@interface MicrophoneB : NSObject<Microphone>
@end
import "MicrophoneB.h"
@implementation MicrophoneB
-(void)song{
NSLog(@"microphoneB song");
}
@end
工厂个人需求persionNeeds
import "Microphone.h"
import "audio.h"
@protocol PersionNeeds<NSObject>
-(id<Microphone>)getMicrophone;
-(id<audio>)getAudio;
@end
import "PersionNeeds.h"
@interface PersionNeedsA : NSObject<PersionNeeds>
@end
@implementation PersionNeedsA
-(id<audio>)getAudio{
return [AudioA new];
}
-(id<Microphone>)getMicrophone{
return [MicrophoneA new];
}
@end
import "PersionNeeds.h"
@interface PersionNeedsB : NSObject<PersionNeeds>
@end
import "PersionNeedsB.h"
import "AudioB.h"
import "MicrophoneB.h"
@implementation PersionNeedsB
-(id<audio>)getAudio{
return [AudioB new];
}
-(id<Microphone>)getMicrophone{
return [MicrophoneB new];
}
@end
测试类
id<PersionNeeds> persionNeeds = [PersionNeedsA new];
id<audio> audio = [persionNeeds getAudio];
id<Micriphone> microphone = [persionNeeds getMicrophone];
[audio audio]; [microphone song]; persionNeeds = [PersionNeedsB new]; audio = [persionNeeds getAudio]; microphone = [persionNeeds getMicrophone]; [audio audio]; [microphone song];
测试结果是
2018-04-03 10:03:55.841091+0800 创建型模式-工厂模式[75521:5357736] audioA audio
2018-04-03 10:03:55.841222+0800 创建型模式-工厂模式[75521:5357736] microphoneA song
2018-04-03 10:03:55.841345+0800 创建型模式-工厂模式[75521:5357736] audioB audio
2018-04-03 10:03:55.841427+0800 创建型模式-工厂模式[75521:5357736] microphoneB song
优点
抽象工厂模式隔离了具体类的生产,使得客户并不需要知道什么被创建。
当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
缺点
增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对“开闭原则”的支持呈现倾斜性。
我们分析下这三种工厂模式
工厂模式其实就是简单工厂模式的升级版本而已,这样就不用简单工厂里面的if else 判断了。而是将if else 中的逻辑用特定类来代替
抽象工厂和工厂模式比较,看UML 图,要是把抽象工厂生产的产品限定是一个的话,那么抽象工厂的图和工厂模式的UML完全相同。可以理解为工厂模式是抽象工厂模式的一种特例。
抽象工厂的产品比简单工厂模式多,所以,就产生了自由组合,demo中,PersionNeedsA 生成的是具体产品是AudioA 和MicrophoneA ,persionNeedB 生成的AudioB 和MicriphoneB。我们也可以组装一个工厂PersionNeedsC生产AudioA和MicriophoneB。
具体代码在demo中
下一篇博客地址
创建性设计模式-建造者模式
网友评论