做系统设计的时候有时会碰到一些无法在父类(或者接口)中抽取通用行为的特性,遇到这种情况就可以采用StringConfigure模式,这个模式我取的名字,不知道是否已经有先人做了总结,如果哪位朋友知道这种模式的正确名称,希望不吝赐教。
以JDBC中取得数据库连接为例,我们可以抽象出数据库的一些公共行为,比如连接数据库都要求提供用户名和密码,因此在JDBC中提供设定连接的用户名和密码的方法。但是另外的一些行为则不一定是所有数据库都具备的,比如对于网络型数据库才需要指定网络地址,而文件型数据库则不需要,再比如在MySQL中需要指定字符集,而其他数据库则不一定需要。如果为了照顾这些特性,为JDBC提供setHostIP、setDBFilePath、setCharSet等方法的话无疑会使得接口变得复杂,会出现很多用不到的方法,并且这些方法也无法覆盖所有未来可能出现的情况,比如某个数据库又增加了允许用户定制连接超时的方法,那么JDBC也要为他提供相应的setTimeOut方法。为了解决这个问题,JDBC提出了连接字符串的概念,这样各个数据库的JDBC驱动只要规定好连接字符串的格式即可,用户把所有的配置信息写到连接字符串中,如果用户修改为其他数据库的话只需修改连接字符串即可,不用修改其他的调用。
使用StringConfigure模式的好处是使得系统中的个性化配置在一个参数中完成,这样保证系统的不同模块的行为的一致性,缺点是配置字符串的格式要由各个实现模块来规定,各个不同实现模块的格式不一致,造成了一定的学习成本,而且无法在开发期发现配置字符串的问题。
这里再来讲一个StringConfigure模式的应用的例子。现在我们要开发一套对IC卡读写器的类库,应用开发人员只要调用不同的IC卡读写子类即可实现操作不同的IC卡读写器。各种不同的IC卡读写器有两个共同的抽象行为:读卡和写卡,即readCard和writeCard,但是各个不同的读卡器还有自己的特性,比如有的读卡器需要指定采用ISO格式还是IBM格式来读写磁卡,有的读卡器需要指定读写操作的分隔符,这些特性不是各个读写器共有的,因此我们采用StringConfigure模式进行设计,开发如下的接口:
interface IICCarder
{
public void writeCard(String data);
public String readCard();
public void configure(String configStr);
}
比如需要指定读写格式的读写器就可以如下实现:
class SomeCarder implements IICarder
{
private FormatEnum format;
public void writeCard(String data)
{
if(format==FormatEnum.IBM)
{
.........
}
else...........
}
public String readCard()
{.............
}
public void configure(String configStr)
{
if(configStr.equls("IBM"))
{
format=FormatEnum.IBM
}
else if(configStr.equls("ISO"))
{
format=FormatEnum.ISO
}
}
}
开发人员使用的时候只要如下调用
IICarder c = new SomeCarder();
c.configure("IBM");
print c.readCard();
如果采用配置文件的话更可以把配置参数写到配置文件中,这样就可以避免修改代码。