老生常谈:工厂模式兄弟姐妹
下面用一个实例来说明工厂模式.
案例:一个视频网站,其中的一个列表页中有个分类导航,需要按类型来查询出相应的视频.这里就定义为:体育,娱乐。取视频并不是简单的依靠类似分类表这样查询,可能查询的方法迥然不同。为了使这个模块具有可扩展性,我在这分别应用工厂模式来设计,看下他们的好处。
工厂模式在设计模式中可谓是个大牌了,应用十分广泛.它一般包含三种方式:
1:简单工厂模式:专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。它又称为静态工厂方法模式,属于类的创建型模式。简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
简单工厂模式的UML类图
简单工厂模式实例:
1:统一的接口IManageList,申明一个取视频信息的方法。
{
DataTable getInformationList();
}
2:体育视频类。
{
DataTable getInformationList()
{//具体方法省略;}
}
3:娱乐视频类。
{
DataTable getInformationList()
{//具体方法省略;}
}
4:工厂类。
{
public static IManageList createInstance(string stype)
{
IManageList list=null;
if(stype=="体育")
{list=new sportsList();}
return list;
}
}
5:client:
DataTable dr=list.getInformationList();
2:工厂方法:工厂方法模式的思想:使一个类的实例化延迟到子类。定义一个用于创建对象的工厂类,由其决定实例化同一抽象类派生出来的具体类。此模式主要包括三个角色:工厂类,抽象类(接口),具体类。
工厂方法类图:
工厂方法实例:
1:统一的接口IManageList,申明一个取视频信息的方法。
{
DataTable getInformationList();
}
2:工厂基类。
{
public abstract IManageList createInstance(string stype);
}
3:具体工厂类。
{
public override IManageList createInstance(string stype)
{//具体代码省略}
}
4:client:
IManageList list=f.createInstance("体育");
DataTable dr=list.getInformationList();
3:抽象工厂
工厂方法的使用者可能会面临两种情况:第一种情况是对于某个产品,我清楚地知道应该使用哪个具体工厂为我服务,于是,我实例化该具体工厂,生产出具体的产品来。第二种情况,我只是需要一种产品,而不想知道也不需要知道究竟是哪个工厂为我生产的,即最终选用哪个具体工厂的决定权在生产者一方,它们根据当前系统的情况来实例化一个具体的工厂返回给使用者,而这个决策过程这对于使用者来说是透明的。
两种情况下具体的实现是不一样的,对于第一种情况,很可能是产品和生产者(工厂)各有一个公共接口,然后不同的具体工厂生产出对应不同的产品,二者出现平行的类结构。第二种情况各个具体生成者的共同父类通过方法的形式对外提供一个接口,返回哪个具体工厂实例的判断逻辑在该方法中实现,使用者通过调用该方法得到具体的工厂实例。
抽象工厂类图:
抽象工厂一般通过工厂方法来实现(还可以通过原型来构造),如果将工厂方法比作一个独立的小厂房,那么抽象工厂就是一个大集团了,在它旗下,集合了很多工厂,虽然生成不同的产品,但是都有该集团的徽号。譬如说,虽然lenovo的鼠标键盘是罗技的,显示器是philips做的,但是都打上了联想的标志。我们买了一套联想的PC,就整套都带有联想的风格,这跟Dell是不一样的。我们平时所说的“look and feel”也就这个道理。你相要哪种风格,就看你选的是哪个集团了。
抽象工厂实例:我们如果扩展一下上面取视频信息的过程,把这部分模块化。如果不是取视频信息而是读取新闻呢,这样工厂方法就不合适了,我们可以定义一个工厂超类来管理他们的子工厂类,提供统一的接口,这样就可以扩展系统功能了。
总结:这三种实现方式各有各的好处。从类图上面来看,根据我介绍的顺序来看,他们越来越复杂,可见他们的功能也是越来越强大。扩展性一个比一个强,解藕能力也是长江后浪推前浪。我们可以像用.net中的服务器绑定控件(Reapeter,DataList,GridView)一样来应用工厂模式,不选最复杂的,只选最适合自己的。
本人对于模式只属于学习阶段,如果有什么地方说错了,还忘大家指教。:)
注:本文参考以下文章:
http://hi.baidu.com/daping_zhang/blog/item/bd85d4397a1437f33a87ce0f.html