核心做用就是为了经过工厂类隐藏对象的建立逻辑,避免暴露给调用方java
以富士康生产不一样类型的Apple Ipad产品为例:android
fun main(args: Array<String>) { val ipadNeeded = FoxconnFactory().product(PadType.AIR) print(ipadNeeded.biometric) } interface IPad { // 搭载的生物认证识别 val biometric: String } enum class PadType { AIR, PRO } // class IpadAir(override val biometric: String = "TouchID") : IPad class IpadPro(override val biometric: String = "FaceID") : IPad // 富士康工厂 class FoxconnFactory { // 生产线 fun product(type: PadType): IPad { return when (type) { PadType.AIR -> IpadAir() PadType.PRO -> IpadPro() } } }
这是比较典型的Java中简单工厂模式,固然利用kotlin特性能够改造下git
用object类替代频繁的FoxconnFactory()对象建立,
用operator操做符重载invoke()来替代fun product()
方法:app
fun main(args: Array<String>) { val ipadNeeded = FoxconnFactory(PadType.AIR) print(ipadNeeded.biometric) } interface IPad { // 搭载的生物认证识别 val biometric: String } enum class PadType { AIR, PRO } // class IpadAir(override val biometric: String = "TouchID") : IPad class IpadPro(override val biometric: String = "FaceID") : IPad // 富士康工厂 object FoxconnFactory { operator fun invoke(type: PadType): IPad { return when (type) { PadType.AIR -> IpadAir() PadType.PRO -> IpadPro() } } }
通常咱们建立对象,要么使用类公有构造器,要么使用类的静态方法返回实例。因此在业务中,咱们一般优先考虑用静态工厂方法来替代构造器,ide
fun main(args: Array<String>) { val ipadNeeded = IPad.FoxconnFactory(PadType.AIR) print(ipadNeeded.biometric) } interface IPad { // 搭载的生物认证识别 val biometric: String //富士康工厂 companion object FoxconnFactory { operator fun invoke(type: PadType): IPad { return when (type) { PadType.AIR -> IpadAir() PadType.PRO -> IpadPro() } } } } enum class PadType { AIR, PRO } // class IpadAir(override val biometric: String = "Touch ID") : IPad class IpadPro(override val biometric: String = "Face ID") : IPad
固然 companion object的自定义名称FoxconnFactory是能够去掉的,直接IPad(IPadType.AIR)函数
kotlin相比较Java设计的强大还在于扩展性,咱们利用kotlin伴生对象的特性隐藏了更多的实现细节,若是须要改造其中的逻辑,咱们仍然能够利用kotlin中的扩展函数特性扩展companion object,增长一个根据生物认证方式获取IPAD屏幕材质的功能布局
fun IPad.FoxconnFactory.getScreenMaterial(biometric: String) = when (biometric) { "TouchID" -> "LCD" "FaceID" -> "OLED" else -> "AMOLED" }
以上即是利用kotlin简单实现了Java中的经典工厂模式,调用方避免直接建立产品对象,而仅仅负责“消费”产品。这是符合开闭原则,对扩展开放、对修改关闭;可是每增长一种类型iPad,都要在工厂类中增长相应的逻辑,这显天然是违背开闭原则的。因此简单工厂模式适用于业务简单的状况下或者具体产品不多增长的状况。而对于复杂的业务环境可能不太适应优化
在Android中的应用google
FragmentFactory()
)onBind(Intent intent)
public abstract Object getSystemService (String name)
方法decodeResourceStream()
构造Bitmap对象的过程针对简单工单的补充,与工厂方法模式相比,若增长产品类型前者是修改工厂,后者是建立新工厂设计
fun main(args: Array<String>) { val ipadNeeded = FoxconnFactory(IpadAirFactory()).producePad() print(ipadNeeded.biometric) } interface IPad { // 搭载的生物认证识别 val biometric: String } class IpadAir(override val biometric: String = "TouchID") : IPad class IpadPro(override val biometric: String = "FaceID") : IPad class IpadMini(override val biometric: String = "TouchID") : IPad // 抽象富士康工厂 abstract class FoxconnFactory{ // 生产不一样pad abstract fun producePad():Pad companion object{ operator fun invoke(factory: FoxconnFactory): FoxconnFactory{ return factory } } } // 生产iPadAir class IpadAirFactory:FoxconnFactory(){ override fun producePad() = IpadAir() } // 生产iPadPro class IpadProFactory:FoxconnFactory(){ override fun producePad()= IpadPro() } // 生产iPadMini class IpadMiniFactory:FoxconnFactory(){ override fun producePad()= IpadMini() }
咱们利用 operator
在抽象工厂类的伴生对象中重载了invoke
方法,从而隐藏抽象类的建立过程,可是调用者仍是会传入具体的工厂类做为参数构造,利用reified关键字的具体化参数类型特性:
fun main(args: Array<String>) { val ipadNeeded = FoxconnFactory<IpadAir>().producePad() print(ipadNeeded.biometric) } interface IPad { // 搭载的生物认证识别 val biometric: String } class IpadAir(override val biometric: String = "TouchID") : IPad class IpadPro(override val biometric: String = "FaceID") : IPad class IpadMini(override val biometric: String = "TouchID") : IPad // 抽象富士康工厂 abstract class FoxconnFactory{ // 对这Apple iPad 一类产品对象声明一个接口 abstract fun producePad():IPad companion object{ inline operator fun<reified T: IPad> invoke(): FoxconnFactory{ return when(T::class){ IpadAir::class -> IpadAirFactory() IpadPro::class -> IpadProFactory() IpadMini::class -> IpadMiniFactory() else-> throw IllegalArgumentException() } } } } // 生产iPadAir class IpadAirFactory:FoxconnFactory(){ override fun producePad() = IpadAir() } // 生产iPadPro class IpadProFactory:FoxconnFactory(){ override fun producePad()= IpadPro() } // 生产iPadMini class IpadMiniFactory:FoxconnFactory(){ override fun producePad()= IpadMini() } //
可是这样在增长产品时候仍是会对工厂进行改动,咱们利用反射替代工厂类的建立
abstract class FoxconnFactory{ // 一类Apple iPad 产品对象声明一个接口 // abstract fun producePad():IPad companion object{ inline operator fun<reified T: IPad> invoke(): IPad?{ var pad: IPad ? = null try { pad = T::class.java.newInstance() as IPad }catch (e: Exception){ e.printStackTrace() } return pad } } }
当有新的iPad产品时,只要建立并继承抽象产品;新建具体工厂继承抽象工厂;而不用修改任何一个类,工厂方法模式是彻底符合开闭原则。可是若是产品种类很是多的时候,好比富士康工厂并不仅是生产Apple的产品若是需求加入华为MatePad生产的需求,这时候产品等级又多了一层品牌商,因此要引入抽象工厂
比较典型的就是Java中的集合类List或者set继承自Collection接口,Collection接口继承于Iterable接口。因此List和Set接口也会继承并实现Iterable中的iterator()方法。而后业务中最经常使用的间接实现类ArrayList和HashSet中的iterator方法就具体构造并返回一个迭代器对象。
工厂方法模式针对单一产品结构,只能抽象一个产品类,具体工厂类也只能生产一个具体产品,而抽象工厂模式是为调用者提供一个接口,能够建立一组相关或者相互依赖的产品对象,也就是有多个抽象产品类,具体工厂类也能生产多个具体产品类
fun main(args: Array<String>) { val applePad = AppleFactory().producePad() val applePhone = AppleFactory().producePhone() val huaweiPad = HuaWeiFactory().producePad() val huaweiPhone = HuaWeiFactory().producePhone() print(applePad.biometric) print(applePhone.cpu) print(huaweiPad.biometric) print(huaweiPhone.cpu) } interface Pad { val biometric: String } interface Phone { // cpu val cpu: String } abstract class AppleIpad : Pad abstract class AppleIphone : Phone class AppleIpadPro(override val biometric: String = "FaceID") : AppleIpad() class AppleIphone11(override val cpu: String = "A13") : AppleIphone() abstract class HuaWeiPad : Pad abstract class HuaWeiMatePhone : Phone class HuaWeiMatePadPro(override val biometric: String = "TouchID") : HuaWeiPad() class HuaWeiMate30(override val cpu: String = "Kirin990") : HuaWeiMatePhone() // 抽象富士康工厂 abstract class FoxconnFactory { // 一类pad产品对象声明一个接口 abstract fun producePad(): Pad // 一类phone产品对象声明一个接口 abstract fun producePhone(): Phone } // 生产Apple产品 class AppleFactory : FoxconnFactory() { override fun producePad(): Pad = AppleIpadPro() override fun producePhone(): Phone = AppleIphone11() } // 生产HuaWei产品 class HuaWeiFactory : FoxconnFactory() { override fun producePad(): Pad = HuaWeiMatePadPro() override fun producePhone(): Phone = HuaWeiMate30() }
这是简单的抽象工厂模式,若是咱们须要增长耳机产品只能再新建个产品类再修改抽象工厂,全部的工厂都会被修改,这也是其缺点,利用上述的反射机制优化一下也是能够的
companion object { inline fun <reified T : Pad> producePad(clz: Class<T>): T? { var product: T? = null try { // 利用反射获取空构造建立对象 product = Class.forName(clz.name).newInstance() as T } catch (e: Exception) { e.printStackTrace() } return product } inline fun <reified T : Phone> producePhone(clz: Class<T>): T? { var product: T? = null try { // 利用反射获取空构造建立对象 product = Class.forName(clz.name).newInstance() as T } catch (e: Exception) { e.printStackTrace() } return product } }
Android中的com.android.internal.policy.IPolicy
是关于Android窗口,窗口管理,布局加载,以及事件回退Handler这一系列窗口相关产品的抽象工厂。
还有就是MediaPlayerFactory生成不一样的MediaPlayer基类,public abstract class MediaPlayerBase implements AutoCloseable
抽象工厂模式不易于拓展新的产品族在通常业务中用的很少。