簡(jiǎn)單工廠模式
-
使用場(chǎng)景
- 工廠類負(fù)責(zé)創(chuàng)建的對(duì)象比較少:由于創(chuàng)建的對(duì)象較少撇吞,不會(huì)造成工廠方法中的業(yè)務(wù)邏輯太過復(fù)雜。
- 客戶端只知道傳入工廠類的參數(shù)裙品,對(duì)于如何創(chuàng)建對(duì)象不關(guān)心:客戶端既不需要關(guān)心創(chuàng)建細(xì)節(jié)忍宋,甚至連類名都不需要記住,只需要知道類型所對(duì)應(yīng)的參數(shù)溜徙。
-
類圖:
-
使用實(shí)例:
- IProduct
interface IProduct { fun use() }
- ProductA
class ProductA : IProduct { override fun use() { println("user-A") } }
- ProductB
class ProductB : IProduct { override fun use() { println("user-B") } }
- factoy
class Factory { fun createProduct(tag: String): IProduct { var product: IProduct? = null when (tag) { "A" -> { product = ProductA() } "B" -> { product = ProductB() } } return product!! } }
- client
fun main(args: Array<String>) { val factory = Factory() factory.createProduct("A").use() factory.createProduct("B").use() }
工廠方法模式
-
使用場(chǎng)景
- 一個(gè)類不知道它所需要的對(duì)象的類:在工廠方法模式中湃缎,客戶端不需要知道具體產(chǎn)品類的類名,只需要知道所對(duì)應(yīng)的工廠即可蠢壹,具體的產(chǎn)品對(duì)象由具體工廠類創(chuàng)建嗓违;客戶端需要知道創(chuàng)建具體產(chǎn)品的工廠類。
- 一個(gè)類通過其子類來指定創(chuàng)建哪個(gè)對(duì)象:在工廠方法模式中图贸,對(duì)于抽象工廠類只需要提供一個(gè)創(chuàng)建產(chǎn)品的接口蹂季,而由其子類來確定具體要?jiǎng)?chuàng)建的對(duì)象,利用面向?qū)ο蟮亩鄳B(tài)性和里氏代換原則疏日,在程序運(yùn)行時(shí)偿洁,子類對(duì)象將覆蓋父類對(duì)象,從而使得系統(tǒng)更容易擴(kuò)展沟优。
- 將創(chuàng)建對(duì)象的任務(wù)委托給多個(gè)工廠子類中的某一個(gè)涕滋,客戶端在使用時(shí)可以無須關(guān)心是哪一個(gè)工廠子類創(chuàng)建產(chǎn)品子類,需要時(shí)再動(dòng)態(tài)指定净神,可將具體工廠類的類名存儲(chǔ)在配置文件或數(shù)據(jù)庫中何吝。
-
類圖:
-
使用實(shí)例:
- Factory
interface Factory<T : Product> { fun createProduct(): T }
- FactoryA
class FactoryA : Factory<ProductA> { override fun createProduct(): ProductA { return ProductA() } }
- FactoryB
class FactoryB : Factory<ProductB> { override fun createProduct(): ProductB { return ProductB() } }
- Product
interface Product { fun user() }
- ProductA
class ProductA : Product { override fun user() { println("Use-A") } }
- ProductB
class ProductB : Product { override fun user() { println("Use-B") } }
- client
fun main() { val factoryA = FactoryA() val factoryB = FactoryB() factoryA.createProduct().user() factoryB.createProduct().user() }
抽象工廠模式
-
使用場(chǎng)景
- 一個(gè)系統(tǒng)不應(yīng)當(dāng)依賴于產(chǎn)品類實(shí)例如何被創(chuàng)建溉委、組合和表達(dá)的細(xì)節(jié),這對(duì)于所有類型的工廠模式都是重要的爱榕。
- 系統(tǒng)中有多于一個(gè)的產(chǎn)品族瓣喊,而每次只使用其中某一產(chǎn)品族。
-屬于同一個(gè)產(chǎn)品族的產(chǎn)品將在一起使用黔酥,這一約束必須在系統(tǒng)的設(shè)計(jì)中體現(xiàn)出來藻三。- 系統(tǒng)提供一個(gè)產(chǎn)品類的庫,所有的產(chǎn)品以同樣的接口出現(xiàn)跪者,從而使客戶端不依賴于具體實(shí)現(xiàn)棵帽。 - 在很多軟件系統(tǒng)中需要更換界面主題,要求界面中的按鈕渣玲、文本框逗概、背景色等一起發(fā)生改變時(shí),可以使用抽象工廠模式進(jìn)行設(shè)計(jì)忘衍。
-
類圖:
-
使用實(shí)例:
- AbstractFactory
interface AbstractFactory { fun <T : AbstractProductA> createProductA(): T fun <T : AbstractProductB> createProductB(): T }
- AbstractProductA
interface AbstractProductA { fun use() }
- AbstractProductB
interface AbstractProductB { fun eat() }
- FactoryA
@Suppress("UNCHECKED_CAST") class FactoryA : AbstractFactory { override fun <T : AbstractProductA> createProductA(): T { return ProductA1() as T } override fun <T : AbstractProductB> createProductB(): T { return ProductB1() as T } }
- FactoryB
class ProductA : Product { override fun user() { println("Use-A") } }
- FactoryB
@Suppress("UNCHECKED_CAST") class FactoryB : AbstractFactory{ override fun <T : AbstractProductA> createProductA(): T { return ProductA2() as T } override fun <T : AbstractProductB> createProductB(): T { return ProductB2() as T } }
- ProductA1
class ProductA1 : AbstractProductA { override fun use() { println("use:A1") } }
- ProductA2
class ProductA2 :AbstractProductA{ override fun use() { println("use:A2") } }
- ProductB1
class ProductB1 :AbstractProductB{ override fun eat() { println("eat:B1") } }
- ProductB2
class ProductB2 : AbstractProductB{ override fun eat() { println("eat:B2") } }
- client
fun main(args: Array<String>) { val f1: AbstractFactory = FactoryA() f1.createProductA<ProductA1>().use() f1.createProductB<ProductB1>().eat() val f2 = FactoryB() f2.createProductA<ProductA2>().use() f2.createProductB<ProductB2>().eat() }