天天看点

【我的《冒号课堂》学习笔记】设计模式(1)创建模式

创建模式

每个设计模式的提出是基于问题的,OOP是以对象为中心的,可对象从何而来?最普遍的作为是通过关键字new和构造器(constructor)。然后从设计的角度看,这种做法却可能存在一定的问题。

构造器第一个弊端:它的名字必须和类名一致,缺乏足够的表现力。

  比如,用Point类来代表平面坐标系的点,它的构造器将有两个参数,分别为横坐标和纵坐标。有时候,我们还希望用极坐标来构造一个点。

  尽管两个构造器参数名不同,但是它们方法签名冲突。

静态工厂方法(static factory method)可解此困局。

【我的《冒号课堂》学习笔记】设计模式(1)创建模式
【我的《冒号课堂》学习笔记】设计模式(1)创建模式

这样处理后代码的可读性和直观性明显增强,美中不足的是该类无法被继承,因为它的构造器是私有的。但此例而言并无被继承的必要。但毋庸置疑,这的确是一个问题,好在我们更提倡用合成来代替继承。

构造器第二个弊端:它的每次调用都伴随着新对象的创建,但这并不总是合适的。

如果不公开构造器,而借助静态工厂方法来提供对象,便可控制对象实例的个数。一方面是出于管理方面的原因,比如单例模式(singleton pattern)便是一个典型的应用;另一个方面是出于性能方面的原因,比如可利用对象池(object pool)来减少对象的创建。最简单的例子莫过于Java中Boolean类提供的valueOf方法

valueOf不会创建新对象,因为它返回的总是Boolean.TRUE和Boolean.FALSE中的一个。由于Boolean类是不可变的(immutable),共享对象不会产生任何问题。在文档中有valueOf方法代替构造器的建议。

构造器第三个弊端是它无法被继承,也就无法多态。

很多时候,客户只关心创建的对象是否能提供某种特定的服务,即在乎的是该对象的社会身份——某个抽象的超类型,而不是它的个体身份——具体类型。可是如果客户直接通过new来创建对象,就必须知道对象的具体类型,从而违背了针对接口编程的原则。此时静态工厂方法再显身手,它可以返回一个具有指定接口的对象,对象的具体类型则不用透露给客户。这些具体类型可以是公开的,也可以是非公开的,还可以是运行期间决定的,甚至可以是动态加载的。

此外,或因设计上的缺陷,或因对象本身的复杂性,不少构造器并没有完成全部的初始化。这不仅会给客户带来额外的负担,也可能破坏对象的一致性。更糟糕的是,这部分逻辑随时可能变化,维护起来很不方便。最好的办法是这种变化隔离出来,单独封装在一个模块中。这个模块可以是一个方法——工厂方法,也可以是一个类——工厂类。

后面的静态工厂 工厂 抽象工厂 建造者模式略

设计模式具体以后另外写笔记

【我的《冒号课堂》学习笔记】设计模式(1)创建模式
【我的《冒号课堂》学习笔记】设计模式(1)创建模式

继续阅读