簡單工廠模式
-
使用場景
- 工廠類負(fù)責(zé)創(chuàng)建的對象比較少:由于創(chuàng)建的對象較少,不會造成工廠方法中的業(yè)務(wù)邏輯太過復(fù)雜。
- 客戶端只知道傳入工廠類的參數(shù),對于如何創(chuàng)建對象不關(guān)心:客戶端既不需要關(guān)心創(chuàng)建細(xì)節(jié),甚至連類名都不需要記住,只需要知道類型所對應(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() }
工廠方法模式
-
使用場景
- 一個(gè)類不知道它所需要的對象的類:在工廠方法模式中,客戶端不需要知道具體產(chǎn)品類的類名,只需要知道所對應(yīng)的工廠即可,具體的產(chǎn)品對象由具體工廠類創(chuàng)建;客戶端需要知道創(chuàng)建具體產(chǎn)品的工廠類。
- 一個(gè)類通過其子類來指定創(chuàng)建哪個(gè)對象:在工廠方法模式中,對于抽象工廠類只需要提供一個(gè)創(chuàng)建產(chǎn)品的接口,而由其子類來確定具體要創(chuàng)建的對象,利用面向?qū)ο蟮亩鄳B(tài)性和里氏代換原則,在程序運(yùn)行時(shí),子類對象將覆蓋父類對象,從而使得系統(tǒng)更容易擴(kuò)展。
- 將創(chuàng)建對象的任務(wù)委托給多個(gè)工廠子類中的某一個(gè),客戶端在使用時(shí)可以無須關(guān)心是哪一個(gè)工廠子類創(chuàng)建產(chǎn)品子類,需要時(shí)再動態(tài)指定,可將具體工廠類的類名存儲在配置文件或數(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() }抽象工廠模式
-
使用場景
- 一個(gè)系統(tǒng)不應(yīng)當(dāng)依賴于產(chǎn)品類實(shí)例如何被創(chuàng)建、組合和表達(dá)的細(xì)節(jié),這對于所有類型的工廠模式都是重要的。
- 系統(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") } }- ProductB2class 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() }