【笨鸟先飞】Java重新学习日记18--设计模式之工厂模式和单例模式(下)

设计模式是面向对象设计的精华,而面向对象终归于继承、封装和多态。我本次学习设计模式重在体会面向对象设计的思维方式,同时知晓该设计模式的应用场景,当后来遇到相似场景,可以直接借用该设计模式思路,而不是自己写一些难以维护的逻辑。

上一章,我学习和思考了,简单工厂模式以及单例模式。剩下的工厂方法和抽象工厂,我认为是在简单工厂模式上,在场景更加复杂的时候,做出的更高级的解决方案。

如果场景有了更多的变化,这个创建特定对象的复杂流程,不只一种。而且每一种之间有巨大差异,但对象却又是同一个类(或者父类)。

举个例子,还是桌面的图标,在不同主题下面,图标的差别是很大的,但是图标始终是icon类或其子类。

这种时候,我们通常还是会采用在简单工厂中,我们可以通过传入参数来区别。当然,已经感觉有点力不从心了。

如果,在代码开发中,可以预见,后面还会有其他的主题方式加入。那么,可以预见,一个是区别的特征参数会增加,而且还需要修改广场类当中的创建对象的方法。每次有新的主题加入,都需要增加一个创建的对象。这个时候简单工厂方法就复杂了。

这个难题,会令我们想到策略模式的使用场景,有多个选择,然后使用判断来进行多个选择中使用哪一个。在策略模式中,我们通过将选择的内容封装成类来解决。

在这里这个思路也同样适用,我们将简单工厂中的多个选择封装成不同的类。也就是,我们常说的,工厂方法模式。

工厂方法模式的核心是通过设定接口创建不只一个工厂子类。

工厂方法使用起来比简单工厂复杂许多,在简单方法里面的工厂类,将变为一个工厂接口,再由多个子类来实现这个接口,从而实现创建不同的对象及其相伴的复杂流程。

在调用时,对于客户端而言,则仍然保留调用接口这一种类型作为入口参数。当然,在实际数据层面,则需要传入多种子类以及复用。

这样做的好处在于保证了“开闭原则”。同样,也几乎满足策略模式所带来的所有优点。

学习到这里,我察觉到有一处值得深思的地方。 策略模式会导致多个类,而工厂模式一种情况是解决多各类的创建。 岂不是策略模式的问题,简单工厂来解决,然后工厂方法又产生了同样的问题?

目前, 在实际工程中,我用到过策略模式,但是没用到过工厂方法。但是可以想象,对于一个足够大的程序,特别是框架等涉及到多个模块交流的程序。这两者就具有意义了,甚至相互促进,从模块A到模块B使用策略模式传递,而从模块B到模块C又使用工厂封装。模块BA结合紧密而和C相对解耦。同时,AC之间通过B来传递一些信息。那么,AB交互一定需要策略模式,而BC之间使用工厂方法能省很多事。

然而我们发现工厂方法有一个缺点,类太多。同时,我们还意识到类很多的原因之一是我们创建一个类是为了一个创建对象的方法,一个类就一个方法。

我们继而发现,比如在设置主题的时候,图标的工厂类一个主题对应一个。但是还有页码的工厂类,壁纸的工厂类,小部件的工厂类。这样一算,一个主题就对应四个类。那类又太多了。

于是,抽象工厂模式就出现了。一个主题是一个大的抽象工厂类,里面包含主题、页码、壁纸、小部件等多个小的工厂类。由一个大的工厂类统御几个小的工厂类,这样客户端在调用的时候,就游刃有余了。

下面来说明,有4种主题,每种主题要初始化4个特殊模式的对象的时候,而且预计后面会变成5个主题的时候,且这些主题的4个特殊对象的初始化参数有2个会变化,且要在8个不同的手机里面使用的时候。抽象工厂模式的优势。

1.不用任何设计模式:

每个手机需要在获取对象的时候,先判断是哪一个主题,然后根据主题模块提供的方法,一一创建4个特殊模式的要素。共计创建16次对象,8个手机共计96次对象创建。后面增加一个主题,需要修改8个手机中的代码,且再创建16此对象。则5个对象共计112次创建。

在修改主题内容实现方案的时候,需要修改8个手机中的112*8 = 896次修改。

可以看到,当调用者很多,且可选对象很多的时候,不使用模式在修改上面难度倍增。

   2.使用简单工厂方法:

每个手机需要在获取对象的时候,先判断是哪一个主题,然后根据主题模块提供的方法传入判断主题的特征值创建对象一次,8个手机共计创建8次。

在工厂类中,需要根据传入参数判断,一一创建4个特殊模式的要素。共计创建16次对象。如果增加一种主题类容,则需要在工厂类中再次创建4个要素。共计创建32次对象。

在修改主题内容实现方案的时候,需要修改工厂类中4个主题的4个要素的个2处类容共计32处。且每次修改都不能出错,一个主题的修改编译不通过,会导致整个类不通过。

这里可以看到,使用工厂方法,代码量大幅度下降。

3.使用工厂方法模式:

每个手机需要在获取对象的时候,先判断是哪一个主题,然后根据主题模块提供的方法使用哪个工厂类来创建对象,8个手机共计创建32次。如果新增工厂,则需要在新增一个类,且在每个手机各按需调用一次该类8次,共计40次。

修改主题内容在4个主题类中分别修改共计32处。如果新增的主题,或者某个主题修改出错,不影响其他主题的发挥。

这里可以看到,使用工程方法模式,性能上比简单方法更复杂,但是耦合性好一些。

4.使用抽象工厂模式:

每个手机需要在获取对象的时候,先判断是哪一个主题,然后根据主题模块提供的方法使用哪个工厂类来创建对象,8个手机共计创建8次。

需要创建4个抽象工厂类(主题),16个产品类(4个主题分别的4个要素)共计20处。新增1个主题,则新增一个抽象工厂类,4个产品类,需要写共计33个类。但是,手机中只创建抽象工厂类的对象,仅8

修改主题内容在4个主题类中分别修改共计32处。如果新增的主题,或者某个主题修改出错,不影响其他主题的发挥。

这里可以看到,使用工程方法模式,性能上和简单方法差不多,而且耦合性还好,但是代码量很大,需要创建的类很多。

从使用的概率来说,简单工厂模式最常用,简单工厂模式的工厂类创建对象的方法内容太多,再考虑使用工厂方法来解耦。

如果解耦后,导致创建对象的次数过多,则使用抽象工厂方法降低客户端创建对象的难度。

一般走到第三步,那都是非常复杂的大型程序了,至少我还没遇到过。

以上就是将创建对象的过程封装起来的设计模式。用来体会面向对象设计,提高编程水平。

本次学习结束语:“用new来创建一个对象,总的来说是属于硬编码”

猜你喜欢

转载自blog.csdn.net/dax120/article/details/79099964
今日推荐