简单工厂模式
-
使用场景
- 工厂类负责创建的对象比较少:由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
- 客户端只知道传入工厂类的参数,对于如何创建对象不关心:客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。
-
类图:
-
使用实例:
- 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() }
工厂方法模式
-
使用场景
- 一个类不知道它所需要的对象的类:在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建;客户端需要知道创建具体产品的工厂类。
- 一个类通过其子类来指定创建哪个对象:在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。
- 将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。
-
类图:
-
使用实例:
- 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() }
抽象工厂模式
-
使用场景
- 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是重要的。
- 系统中有多于一个的产品族,而每次只使用其中某一产品族。
-属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。- 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。 - 在很多软件系统中需要更换界面主题,要求界面中的按钮、文本框、背景色等一起发生改变时,可以使用抽象工厂模式进行设计。
-
类图:
-
使用实例:
- 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() }