8.1 女娲造人的故事
8.1 女娲造人的故事
东汉《风俗通》记录了一则神话故事:“开天辟地,未有人民,女娲搏黄土做人”,讲述的内容就是大家非常熟悉的女娲造人的故事。开天辟地之初,大地上并没有生物,只有苍茫大地,纯粹而洁净的自然环境,寂静而又寂寞,于是女娲决定创造一个新物种(即人类)来增加世界的繁荣,怎么制造呢?
别忘了女娲是神仙,没有办不到的事情,造人的过程是这样的:首先,女娲采集黄土捏成人的形状,然后放到八卦炉中烧制,最后放置到大地上生长,工艺过程是没有错的,但是意外随时都会发生:
第一次烤泥人,感觉应该熟了,往大地上一放,哇,没烤熟!于是一个白人诞生了! (这也是缺乏经验的最好证明。)
第二次烤泥人,上一次没烤熟,这次多烤一会儿,放到世间一看,嘿,熟过头了,于是黑人诞生了!
第三次烤泥人,一边烧制一边察看,直到表皮微黄,嘿,刚刚好,于是黄色人种出现了!
这个造人过程是比较有意思的,是不是可以通过软件开发来实现这个过程呢?古人云:“三人行,必有我师焉”,在面向对象的思维中,万物皆对象,是对象我们就可以通过软件设计来实现。首先对造人过程进行分析,该过程涉及三个对象:女娲、八卦炉、三种不同肤色的人。女娲可以使用场景类Client来表示,八卦炉类似于一个工厂,负责制造生产产品 (即人类),三种不同肤色的人,他们都是同一个接口下的不同实现类,都是人嘛,只是肤色、语言不同,对于八卦炉来说都是它生产出的产品。分析完毕,我们就可以画出如图8-1所示的类图。
我们定义的每个人种都有两个方法:getColor(获得人的皮肤颜色)和talk(交谈),其源代码如代码清单8-1所示。
代码清单8-1 人类总称
1 | public interface Human { |
接口Human是对人类的总称,每个人种都至少具有两个方法,黑色人种、黄色人种、白色人种的代码分别如代码清单8-2、代码清单8-3、代码清单8-4所示。
代码清单8-2 黑色人种
1 | public class BlackHuman implements Human { |
代码清单8-3 黄色人种
1 | public class YellowHuman implements Human { |
代码清单8-4 白色人种
1 | public class WhiteHuman implements Human { |
所有的人种定义完毕,下一步就是定义一个八卦炉,然后烧制人类。我们想象一下,女娲最可能给八卦炉下达什么样的生产命令呢?应该是“给我生产出一个黄色人种 (YellowHuman类)”,而不会是“给我生产一个会走、会跑、会说话、皮肤是黄色的人种”, 因为这样的命令增加了交流的成本,作为一个生产的管理者,只要知道生产什么就可以了, 而不需要事物的具体信息。通过分析,我们发现八卦炉生产人类的方法输入参数类型应该是Human接口的实现类,这也解释了为什么类图上的AbstractHumanFactory抽象类中createHuman 方法的参数为Class类型。其源代码如代码清单8-5所示。
代码清单8-5 抽象人类创建工厂
1 | public abstract class AbstractHumanFactory { |
注意,我们在这里采用了泛型(Generic),通过定义泛型对createHuman的输入参数产生两层限制:
- 必须是Class类型;
- 必须是Human的实现类。
其中的”T”表示的是,只要实现了Human接口的类都可以作为参数,泛型是JDK 1.5中的一个非常重要的新特性,它减少了对象间的转换,约束其输入参数类型,对Collection集合下的实现类都可以定义泛型。有关泛型的详细知识,请参考相关的Java语法文档。
目前女娲只有一个八卦炉,其实现生产人类的方法,如代码清单8-6所示。
代码清单8-6 人类创建工厂
1 | public class HumanFactory extends AbstractHumanFactory { |
人种有了,八卦炉也有了,剩下的工作就是女娲采集黄土,然后命令八卦炉开始生产, 其过程如代码清单8-7所示。
代码清单8-7 女娲类
1 | public class NvWa { |
人种有了,八卦炉有了,负责生产的女娲也有了,激动人心的时刻到来了,我们运行一下,结果如下所示。
1 | --造出的第一批人是白色人种-- |
哇,人类的生产过程就展现出来了!这个世界就热闹起来了,黑人、白人、黄人都开始活动了,这也正是我们现在的真实世界。以上就是工厂方法模式(没错,对该部分有疑问,请继续阅读下去)。