设计模式 - 工厂 Factory Method Pattern

文章参考来源

一、概念

创建简单的对象直接 new 一个就完事,但对于创建时需要各种配置的复杂对象例如手机,没有工厂的情况下,用户需要自己处理屏幕、摄像头、处理器等配置,这样用户和手机就耦合在一起了。 

  • 可以使代码结构清晰,有效地封装变化:在编程中,产品类的实例化有时候是比较复杂和多变的,通过工厂模式,将产品的实例化封装起来,使得调用者根本无需关心产品的实例化过程,只需依赖工厂即可得到自己想要的产品。
  • 对调用者屏蔽具体的产品类:如果使用工厂模式,调用者只关心产品的接口就可以了,至于具体的实现,调用者根本无需关心。即使变更了具体的实现,对调用者来说没有任何影响。
  • 降低耦合度:产品类的实例化通常来说是很复杂的,它需要依赖很多的类,而这些类对于调用者来说根本无需知道,如果使用了工厂方法,我们需要做的仅仅是实例化好产品类,然后交给调用者使用。对调用者来说,产品所依赖的类都是透明的。

二、简单工厂模式

  • 优点:封装了对象的创建,与业务逻辑解耦。
  • 缺点:每当具体产品数量增加时,都需要对工厂类进行修改,不符合开闭原则且会越来越臃肿。

抽象产品

IProduct

简单工厂创建的多有对象的父类,负责描述所有实例共有的公共接口。

具体产品

ConcreteProduct

简单共厂模式的创建目标。

简单工厂

SimpleFactory

负责创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。

2.1 抽象产品 (手机)

interface IPhone {
    fun show()
}

2.2 具体产品(手机A、手机B)

class PhoneA : IPhone {
    override fun show() {
        println("Phone A")
    }
}

class PhoneB : IPhone {
    override fun show() {
        println("Phone B")
    }
}

2.3 简单工厂

enum class PhoneModel { A, B }    //使用枚举,方便对传入的型号做判断

class SimpleFactory {
    companion object {
        fun makePhone(phoneModel: PhoneModel): IPhone = when (phoneModel) {
            PhoneModel.A -> PhoneA()
            PhoneModel.B -> PhoneB()
        }
    }
}

2.4 使用

SimpleFactory.makePhone(PhoneModel.B)

三、工厂方法模式

  • 优点:每当具体产品增加时,只需创建对应的具体工厂即可,对已有代码无修改,符合开闭原则便于扩展。
  • 缺点:具体工厂只能生产一种产品。
抽象产品 工厂方法模式所创建的对象的超类型。也是产品对象的共同父类或者共同拥有的接口。
具体产品 实现了抽象产品角色所定义的接口。某具体产品由具体工厂创建,他们往往一一对应。
抽象工厂 定义了创建抽象产品的方法,任何在模式中创建对象的工厂类都必须实现这个接口。
具体工厂 实现抽象工厂接口的具体工厂类,负责生产具体的产品。

3.1 抽象产品(衣服)

interface Icloth {
    fun show()
}

3.2 具体产品(外套、牛仔裤)

class Coat : Icloth {
    override fun show() {
        println("夹克")
    }
}

class Jeans : Icloth {
    override fun show() {
        println("牛仔裤")
    }
}

3.3 抽象工厂

interface Ifactory {
    fun makeCloth(): Icloth
}

3.4 具体工厂(夹克工厂、牛仔裤工厂)

class CoatFactory : Ifactory {
    override fun makeCloth() = Coat()
}

class JeansFactory : Ifactory {
    override fun makeCloth() = Jeans()
}

3.5 使用

val coatFactory = CoatFactory()
val coat = coatFactory.makeCloth()

四、抽象工厂模式

  • 优点:每当具体产品族(这里指阿迪或耐克)增加时,只需要创建对应的具体工厂即可,对已有代码无修改,符合开闭原则便于扩展。
  • 缺点:每当新增

4.1 抽象产品(鞋子、衣服)

interface IShoes {
     fun show()
}

interface ICloth {
     fun show()
}

4.2 具体产品(阿迪鞋子、阿迪衣服、耐克鞋子、耐克衣服)

class AdidasShoes : IShoes {
    override fun show() {
        println("阿迪鞋子")
    }
}

class AdidasCloth : ICloth {
    override fun show() {
        println("阿迪衣服")
    }
}

class NikeShoes : IShoes {
    override fun show() {
        println("耐克鞋子")
    }
}

class NikeCloth : ICloth {
    override fun show() {
        println("耐克衣服")
    }
}

4.3 抽象工厂

interface Ifactory {
    fun makeCloth(): ICloth
    fun makeShoes(): IShoes
}

4.4 具体工厂(阿迪工厂、耐克工厂)

class AdidasFactory : Ifactory {
    override fun makeShoes(): IShoes = AdidasShoes()
    override fun makeCloth() = AdidasCloth()
}

class NikeFactory : Ifactory {
    override fun makeShoes(): IShoes = NikeShoes()
    override fun makeCloth() = NikeCloth()
}

4.5 使用

val adidasFactory = AdidasFactory()
val adidasCloth = adidasFactory.makeCloth()

猜你喜欢

转载自blog.csdn.net/HugMua/article/details/130660695