定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化,延迟到其子类
工厂方法模式是对简单工厂模式进一步的解耦,在工厂方法模式中是一类产品对应一个工厂类,而这些工厂类都继承于一个抽象工厂。这相当于是把原本会随着业务扩展而庞大的简单工厂类,拆分成一个的具体产品工厂类,这样代码就不会都耦合在同一个类中。
(1).良好的封装性,在工厂方法模式中,工厂方法用来创建业务所需要的产品,同时还向客户隐藏了具体产品的创建细节,只需要关心所需产品的工厂,降低了模块间的耦合性。
(2).良好的扩展性,在当系统中需要加入新产品时,无需修改抽象工厂和抽象产品提供的接口,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以完成系统的扩展。
(3).屏蔽产品类,这一特点非常重要,产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,只要接口保持不变,系统中的上层模块就不会发生变化。
当需要新增产品时,都必须要编写新的具体产品类,还要提供与之对应的具体工厂类,随着类的不断增加,在一定程度上增加了系统的复杂度,会有更多的类需要编译和加载,会给系统带来一些额外的开销。
对比简单工厂,简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件通过判断动态的实例化相关的类,对于客户端来说,去除了与具体产品的依赖。但是如果想添加一种产品就得去修改工厂的判断逻辑,这就违背了对修改关闭的原则。
工厂方法模式,就是解决的简单工厂的工厂类的耦合,根据依赖倒置原则,我们把工厂类抽象出一个接口,这个借口只有一个方法,就是创建抽象产品的工厂方法。然后,所有的要生产具体类的工厂,就去实现这个接口,这样,一个简单工厂模式的工厂类,变成了一个工厂抽象接口和多个具体生成对象的工厂,于是我们在增加产品的时候,就不需要改变原有的工厂类了,只需要增加此功能的产品类和工厂类就可以了。这样整个工厂和产品其实都没有修改的变化,而只是扩展的变化,这就完全符合开放-封闭原则的精神。
工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法吧简单工厂的内部逻辑判断移到了客户端代码来进行。如果想要添加功能,原来是修改工厂类的,现在是修改客户端。
- //产品类的抽象接口
- interface Operation{
- fun calculation(var1: Int, var2: Int): Int
- }
- //工厂类的抽象接口
- interface OperationFactory{
- fun createOperation() : Operation
- }
- //产品类实现类加
- class PlusOperation : Operation{
- override fun calculation(var1: Int, var2: Int): Int {
- return var1 + var2
- }
- }
- //产品实现类减
- class SubtractionOperation : Operation{
- override fun calculation(var1: Int, var2: Int): Int {
- return var1 - var2
- }
- }
- //工厂实现类加法工厂
- class PlusFactory : OperationFactory{
- override fun createOperation(): Operation {
- return PlusOperation()
- }
- }
- //工厂实现类减法工厂
- class SubtractionFactory : OperationFactory{
- override fun createOperation(): Operation {
- return SubtractionOperation()
- }
- }
- //客户端
- fun main() {
- //使用加法计算1 + 1
- val plusFactory = PlusFactory() // 选择哪个产品工厂从简单工厂里移动到客户端这里
- val plusOperation = plusFactory.createOperation()
- println(plusOperation.calculation(1,1))
- //使用减法计算1 -1
- val subtractionFactory = SubtractionFactory()
- val subtractionOperation = subtractionFactory.createOperation()
- println(subtractionOperation.calculation(1,1))
- }
通过抽象方法我体会到
1.抽象封装了变化,简单工厂是在工厂中通过逻辑判断去生产产品,当增加或者减少产品时,就得去修改代码,这个就是变化。
通过抽象变化,上面的代码中变化就是加法减法这些运算,对于工厂来说,变化就是生产不同的运算,我们通过抽象生产不同运算运算,让不同的实现类去实现所有的运算规则,这样就解耦了变化,就可以把变化移动到客户端。
2.依赖倒置原则
依赖倒置原则:要依赖抽象,不要依赖具体类。
听起来像是针对接口编程,不针对实现编程,但是这个原则说明了:不能让高层组件依赖底层组件,而且,不管高层或底层组件,两者都应该依赖于抽象。