在面向对象的编程中,工厂模式是一种经常被使用到的模式。根据工厂模式实现的类可以根据提供的数据生成一组类中某一个类的实例,通常这一组类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作。
工厂模式的原理
为了理解工厂模式是如果工作的,让我们来看一下图一:
图1工厂模式的工作原理
在图1中,X是基类,Xy和Xz继承了X类。而工厂类能够根据程序传递给它的数据决定生成那一个子类的实例。在右边定义了一个getClass方法,该方法需要参数a并返回一个X类的实例。对于程序员来说,返回的究竟是Xy还是Xz的实例并不重要,因为它们有相同的方法,只不过这些方法的内部实现不同罢了。
一个简单的例子
在什么情况下会使用到工厂模式呢?让我们来看一个简单的例子。在一些网上的调查表中,经常要求填写姓名。有些人填写时姓放在前面,名放在后面(例如中国人填写姓名的习惯);而有些人填写时采用"名,姓"或者"姓,名"的格式(西方大多数文化中都这样填写姓名)。现在让我们假设通过判断姓名中是否包含了","和空格就可以判断到底是姓在前面还是名在前面。下面然我们先定义一个基类Namer:
indexof空格算不算在基类中我们将姓和名保存在两个不同的变量中,并且提供了getFirst()和getLast()方法。由于子类需要使用到保存姓名的变量,因此我们将它们设定为Protected。
现在我们可以实现两个类来区分上面提到的两种情况。在WithoutComma类中,我们假设如果读入字符串中没有空格,则第一个字符是姓,剩下的字符是名;否者第一个空格之前是名,其后是姓:
对于姓名中包含逗号的情况,代码如下。
接下来就需要实现工厂类了。在工厂类中,我们只需要根据输入的名称中是否带有逗号来生成不同的类的实例。
我们可已通过图二中的例子来看一看在程序中如何使用工厂类:
图2工厂模式测试程序
在程序中,首先需要初始化工厂类:
然后当"获得姓名"按钮被按下以后,调用computeName()方法,而该方法又调用工厂类的getNamer()方法获得Namer的实例,并将姓和名显示在相应的文本框中:
程序的源代码如下: