设计模式(二)--简单工厂、工厂方法、抽象工厂

引用:愤怒的韭菜,个人觉得他总结的很精辟,易于理解。同时觉得博文格式也很喜欢。

这三种模式表现的是在不同程度的抽象,选在使用哪一种,取决工程性质。

定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。

类图:

设计模式(二)--简单工厂、工厂方法、抽象工厂

三种工厂方法的演变:

简单工厂:

设计模式(二)--简单工厂、工厂方法、抽象工厂

工厂方法:

设计模式(二)--简单工厂、工厂方法、抽象工厂

抽象工厂:

设计模式(二)--简单工厂、工厂方法、抽象工厂

适用场景:

        不管是简单工厂模式,工厂方法模式还是抽象工厂模式,他们具有类似的特性,所以他们的适用场景也是类似的。

        首先,作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过new就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

       其次,工厂模式是一种典型的解耦模式,迪米特法则在工厂模式中表现的尤为明显。假如调用者自己组装产品需要增加依赖关系时,可以考虑使用工厂模式。将会大大降低对象之间的耦合度。

       再次,由于工厂模式是依靠抽象架构的,它把实例化产品的任务交由实现类完成,扩展性比较好。也就是说,当需要系统有比较好的扩展性时,可以考虑工厂模式。

这里博主的例子:客户端和造车之间的关系

客户端,直接使用引擎、车轮之类的。这里表现的几点:1、客户端应该与车这个概念直接相关,而不是配件(迪米特法则)

2、这里这些配件时实体,当为抽象时,客户端可能根本无法使用。3、这些配件之间组合为车,并不是毫不相关的。就如,买车的人不必知道车的生产组装过程,不同的车的组装生产过程也不相同。

结果:客户--工厂(需要一辆车)--工厂(生产不同的车,按不同车的生产方法,配件使用)

《设计模式》是:老人与雷锋之间的关系、运算类与运算工厂的关系

直接:老人--雷锋

工厂方法:老人——志愿者社区——志愿者、学雷锋的大学生

抽象工厂的例子:SqlDB 和AccessDB 的切换

我们来看书中演化过程:

第一版:这里问题是:修改只针对User表的使用进行分类,但实际情况数据库怎么会只使用一个表。那么每增加一个表,就需要增加对应处理的类。

设计模式(二)--简单工厂、工厂方法、抽象工厂


第二版:这里可以应对多个表的操作,问题时,每新增一个表,表两个类的处理。这种扩展的方法是非常糟糕的,每当有两种以上,多种变化混在一起的时候,制作接口,将变化封装。这里数据库这个例子很典型,表现的就是,两种数据库切换,且在程序的任何地方都会用到。封装就显得更有必要。因为如果需要修改数据库,任何指明使用哪种数据库的地方都需要修改。

设计模式(二)--简单工厂、工厂方法、抽象工厂

第三版:采用简单工厂简化,DataAccess封装了基本的数据库操作,不同数据库语法,执行操作时,内部自行处理。IUser、IDepartment提供了创建实例,用户创建实例,根据使用不同数据库,自行创建实例。用户接触到的,都是抽象的接口。这里体现了抽象的主要思想:编码时采用抽象接口,运行时进行实例化。接口、抽象的使用。

设计模式(二)--简单工厂、工厂方法、抽象工厂

最后,作者用反射的机制,把抽象工厂中的case分支,去掉了。

抽象工厂,是对工厂模式的更进一步的抽象。客户端需要买车,直接对工厂,现实中,那么多的造车工厂,进一步抽象,客户只需要接触一个卖车的销售员。这里就诠释了,文章开头的定义。