Design Patterns 创建模式 之 Factory 工厂模式

[b][size=large][color=red]1 Factory[/color][/size][/b]
意图:提供一个创建一系列相关和相互依赖对象的接口,而无需指定他们具体的类。
假设我们需要进行各种数据库操作,可是我们有很多的选择啊,JDBC,Hibernate,Ibatis等等。本来选择一个就OK了,可是变态的Boss为了炫耀我们的技术如何如何强大,竟说我们能够无成本地在这三个解决方案间切换。这下系统该怎么设计呢?
或许你已经注意到每种解决方案自身都是完备而独立的,不错,这便是解决问题的切入点。提供一套解决方案公有行为的接口,各个解决方案分别实现这些接口,同时建立一个创建各个解决方案的工厂(Factory)。这不就完成任务了吗?

[b][size=medium]1.1 Simple Factory[/size][/b]
首先,如果一个客户要用到一款手机,一般的做法是自己去创建一款手机,然后拿来用,如图:
[img]http://dl.iteye.com/upload/picture/pic/66452/7a4ed4ba-1053-3e9c-aadd-400c1f598108.bmp[/img]
这时,客户需要知道怎么去创建手机,与手机紧密的耦合起来了。如是简单工厂模式如下:
[img]http://dl.iteye.com/upload/picture/pic/66572/74cee9eb-b2f6-3796-b5b5-87355eca4312.bmp[/img]
[color=darkblue][b]1),手机抽象类:[/b][/color]
public abstract class Mobile {

}
[color=darkblue][b]2),手机实现类[/b]:[/color]
Nokia实现类:
public class MobileNokia extends Mobile{
MobileNokia() {
System.out.println("I am Nokia!");
}
}

Iphone实现类:
public class MoblieIphone extends Mobile{
MoblieIphone() {
System.out.println("I am Iphone!");
}
}
[color=darkblue][b]3),工厂类[/b]:[/color]
public class MobileFactory {
public static Mobile creatMobileInstance(String type) {
if ("Nokia".equals(type)) {
return new MobileNokia();
} else if ("Iphone".equals(type)) {
return new MoblieIphone();
} else {
return null;
}
}
}

我要Iphone
MobileFactory.creatMobileInstance("Iphone");

简单工厂模式往往是普通工厂模式的一个特例。简单工厂模式基本是用一个类来模拟工厂,通过该工厂类的静态方法返回具体的产品类,而这些产品又源自一个抽象的产品(当然,这儿可能会存在多种抽象产品,即有多种不同类型的产品,如蔬菜、瓜果等等),即静态工厂模式。书中提及了几个对象:水果以及具体的水果,园丁;园丁根据得到的参量来决定提取某种水果。如果存在多种抽象产品,必须考察抽象产品是由抽象类来实现还是用接口来表现了,如果具体产品之间拥有共同的商业逻辑,一般都应用抽象类来表现,否则应用接口来表现,在一个类型的等级结构中,将共同的部分尽量向上塑造。相应的,工厂也可以分为多个工厂,各自负责不同种类的产品即抽象类。

考虑一下,如果我们新增了一种产品,那么在我们的静态工厂类中就必须再加入返回该新增的产品类的方法,是需要修改这个工厂类的。这个到底应该如何才能不修改工厂类呢?或许我们的工厂类不应该同具体产品类来发生关联关系。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[b][size=medium]1.2 Factory Method[/size][/b]
[img]http://dl.iteye.com/upload/picture/pic/66574/c7c1bd64-1464-3e59-863f-219a9db3072a.bmp[/img]
当产品增加的时候,并不需要改动抽象工厂(提供给外部的接口),只需要改动工厂实现类即可。
例子 产品:
public abstract class Mobile {
}
public class MobileNokia extends Mobile{
MobileNokia() {
System.out.println("I am Nokia!");
}
}
public class MoblieIphone extends Mobile{
MoblieIphone() {
System.out.println("I am Iphone!");
}
}

工厂
public interface class Factory {
public Mobile createMobile();
}
public class FactoryNokia implements Factory{

public Mobile createMobile() {
return new MobileNokia() ;
}
}
public class FactoryIphone implements Factory {

public Mobile createMobile() {
return new MoblieIphone() ;
}
}

测试
public class Main {
public static void main(String[] args) {
Factory factoryNokia = new FactoryNokia();
factoryNokia.createMobile();
Factory factoryIphone = new FactoryIphone();
factoryIphone.createMobile();
}
}

工厂方法模式是类的创建模式,定义一个创建工厂接口,将实际的创建工作推到子类工厂中。也就是原本的静态类变成了一个抽象类或接口,而将制造的任务交给底下的具体实现类来完成。工厂方法模式似乎同抽象工厂模式很类似,但或许引入产品族后可以做一下比较。

抽象产品A(具体产品A1, 具体产品A2),抽象工厂F可以只有一个具体工厂,实现生成A的抽象方法。即工厂方法模式是将注意集中在可抽象产品概念上(意即多个具体产品可抽象化)。

如果引入产品族的概念,即有多个抽象产品,那么就必须对应不同的抽象产品形成不同的抽象工厂层,这会打破工厂的独立性,乃至形成一个庞大的工厂族。自然工厂方法模式不能很好的解决这种问题。因为有了产品族的引入,自然就引入了抽象工厂模式。


用工厂来作新产品有点浪费....
不如用状态位来区分产品
工厂是用在方法实现上有区别的业务类中的.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[b][size=medium]1.3 Abstract Factory[/size][/b]
解决问题的切入点是“每种解决方案自身都是完备而独立的”,所以这些具体的各种解决方案的工厂对Consumer也应该是透明的。于是我们给这些工厂(解决方案)加上一个工厂,也就是我们通过这个工厂来生成一整套的解决方案。这个工厂便是我们要说的AbstractFactory
本着重构的精神,工厂类应该由工厂自身来解决,不应该由客户去创建。把它和接口Factory合而为一,成为一个抽象类。大概这便是这种设计模式名字的由来吧。
例子如下:
产品:
public abstract class Mobile {
}
public class MobileNokia extends Mobile{
MobileNokia() {
System.out.println("I am Nokia!");
}
}
public class MoblieIphone extends Mobile{
MoblieIphone() {
System.out.println("I am Iphone!");
}
}


工厂:
public abstract class AbstractFactory {
/**
* 根据不同的体系要求创建出不同的业务工厂
* @param factoryName
* @return
*/
public static AbstractFactory getFactory(String factoryName) {
AbstractFactory factory = null;
if ("nokia".equals(factoryName)) {
factory = new FactoryNokia();
} else if ("iphone".equals(factoryName)) {
factory = new FactoryNokia();
}
return factory;
}
/**
* 建立各个业务接口,由各实现的工厂来创建具体的Mobile
* @return
*/
public abstract Mobile createMobile();
}
public class FactoryNokia extends AbstractFactory{
@Override
public Mobile createMobile() {
return new MobileNokia() ;
}
}
public class FactoryIphone extends AbstractFactory {
@Override
public Mobile createMobile() {
return new MoblieIphone() ;
}
}
public class Main {
public static void main(String[] args) {
AbstractFactory factoryNokia = AbstractFactory.getFactory("nokia");
factoryNokia.createMobile();
AbstractFactory factoryIphone = AbstractFactory.getFactory("iphone");
factoryIphone.createMobile();
}
}


小结
正如我上面举的这个例子,抽象工厂模式主要适用于需要提供若干种不同实现体系,但又要求有相同处理要求的时候。如Portal技术中,各种Portlet便是不同的体系,但我们在处理Portal的时候都是把他们统一当作Portlet实现,同样这种解决问题的思路可以用在SOA中。这种设计模式大多出现在各个系统进行集成的时候。

[size=x-large][b]spring中管理bean的方式,对各Factory进行管理[/b][/size]

1,首先规定好一种管理格式
<beans>   
<bean id="A" class="com.javaeye.pouyang.FactoryNokia" />
<bean id="B" class="com.javaeye.smartfool.FactoryIphone" />
</beans>

2,修改Factory
这样,我们可以在AbstractFactory加入一个读配置的方法getXmlClass,通过输入id值来读出其对应的class名。这样,我们的AbstractFactory变成
public abstract class AbstractFactory {   

// 读取配置文件
private static String getXmlClass(String id){
......
}

public static AbstractFactory getFactory(String factoryName) {
AbstractFactory ist = null;
String className = getXmlClass(factoryName);
try {
ist = (AbstractFactory) Class.forName(className).newInstance();
} catch (Exception e) {
e.printStackTrace();
ist = null;
}
return ist;
}

public abstract Service createService();
}

这样,就可以解除AbstractFactory对子类的依赖了。
without ejb 很好的一本书! 非常感谢lintomny
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值