一、本质:
是一种实现了“工厂”概念的面向对象设计模式,处理在不指定对象具体类型的情况下创建对象的问题。
工厂方法模式的实质是:定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。
二、要解决的问题:
是对象的创建时机,它提供了一种扩展的策略,很好地符合了开放封闭原则。
工厂方法也叫做虚构造器(Virtual Constructor).又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
三、安全性:
工厂方法创建对象与直接创建新的对象相比,工厂方法模式让客户程序可以要求由工厂方法创建的对象拥有一组共同的行为。所以往类层次结构中引入新的具体产品并不需要修改客户端代码,因为返回的任何具体对象的接口都跟客户端一直在用的从前的接口相同。
四、优点:
1:将对象的创建和对象本身业务处理分离可以降低系统的耦合度,使得两者修改起来都相对容易。
2:在调用工厂类的工厂方法时,由于工厂方法是静态方法,使用起来很方便,可通过类名直接调用,而且只需要传入一个简单的参数即可,在实际开发中,还可以在调用时将所传入的参数保存在XML等格式的配置文件中,修改参数时无须修改任何源代码。
3:简单工厂模式最大的问题在于工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,这一点与开闭原则是相违背的。
4:简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。
五、使用场景
1:编译时无法准确预期要创建的对象的类;
2:类想让子类决定在运行时创建什么;
3:类有若干辅助类为其子类,而你想将返回哪个子类这一信息局部话;
工厂方法在CocoaTouch中的应用
工厂方法在CocoaTouch中几乎随处可见,也称作“类簇”。在Objective-C中常见的两步对象创建法[[SomeClass alloc] init].但是还有一些便利的创建方法。例如,NSNumber有很多numberWith*方法;其中有两个是numberWithBool:和numberWithChar:。它们是类方法,也就是说我们向NSNumber发送[[NSNumber numberWithBool:bool]]与[[NSNumber numberWithChar:char]],以获得与传入参数同类型的各种NSNumber实例。与如何创建NSNumber的具体子类型的实例有关的所有细节,都有NSNumber的类工厂方法负责。[[NSNumber numberWithBool:bool]]的情况是,方法接受值bool,并把NSNumber的内部子类的一个实例初始化,让它能够反应传入的值。
优点
1:一个调用者想创建一个对象,只要知道其名称就可以了。
2:扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
3:屏蔽产品的具体实现,调用者只关心产品的接口。
缺点
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
下面的代码通过 Drinking 的工厂方法将可乐和啤酒两个私有类进行了类簇化:
class Drinking {
typealias LiquidColor = UIColor
var color: LiquidColor {
return .clear
}
class func drinking(name: String) -> Drinking {
var drinking: Drinking
switch name {
case "Coke":
drinking = Coke()
case "Beer":
drinking = Beer()
default:
drinking = Drinking()
}
return drinking
}
}
class Coke: Drinking {
override var color: LiquidColor {
return .black
}
}
class Beer: Drinking {
override var color: LiquidColor {
return .yellow
}
}
let coke = Drinking.drinking(name: "Coke")
coke.color // Black
let beer = Drinking.drinking(name: "Beer")
beer.color // Yellow”