在网上看了很多这方面的资料,头也大了,众说纷纭,但都大同小异,按我自己的理解总结了一下:
Factory模式可以分为:简单工厂(Simple Factory)、工厂方法(Factory Method)、抽象工厂(Abstract Factoty)
下面分别来说明下:
简单工厂(Simple Factory)是比较容易理解的,主要是一个具体的全能类,负责产生所有的之类,根据传来的参数进行比较产生相对应的之类,简单工厂方法没有抽象出方法。用列说面如下:
public static Product factory(String which) throw NoSuchProductExcption
{
if(which.equalIgnoreCase("product1"))
{
return new Product1();
}
else if(which.equalsIgnoreCase("product2"))
{
return new Product2();
}
else if(which.equalsIgnoreCase("product3"))
{
return new Product3();
}
else throw NoSuchProductExcption("NoSuchProduct");
}
}
}
主要要区分和理解是的
工厂方法(Factory Method)和 抽象工厂(Abstract Factoty)
工厂方法:一个抽象类或接口,他只定义方法,具体实现有继承或他的实现之类来完成
是用来产生一个(请大家注意是一个,我想这也很关键)对象的。我的意思是说,工厂方法模式的一个最核心的地方就是你们利用一个子类,让它来决定如何完成一个具体对象的生成工作。通过这种方式,客户端(调用者所在的类)只需要知道这个对象的抽象类型,而子类呢才关心这个抽象类型的真正实现类。所以呢,换句话说,我能分离客户端和具体的实现类。
抽象工厂:也是一个抽象类,和工厂方法没有多大区别,在于创建对象的复杂程度.
提供了一个抽象类(通常来说是接口)来创建一个产品家族。这个抽象类的子类来定义这些产品是如何被生产的。为了使用这个工厂,你声明一个,然后再把一个子类通过参数传递,来对它赋值{也就是说,在一个客户端类里先声明一个抽象的工厂类,然后比如说可以在它的构造函数里留个参数是个抽象类型(抽象工厂类)的,在实例化这个客户端的时候把抽象工厂类的子类(也即是哪个产品族)传进来,从而在构造函数里完成对这个抽象类的实例化。}(在抽象类里的一组方法返回的都是抽象产品)所以呢,跟工厂方法一样,我也分离了客户端和它们要使用的究竟是哪种具体的产品。
根本区别:工厂方法是让类来负责创建对象的工作而抽象工作是使用一堆的对象
以下例题(转)
对于工厂方法来说
实质上它是让工厂实现了抽象的工厂接口,它把具体怎么生产一种东西,放在具体的工厂去实现了,所谓”延迟到子类中实现“
public interface Creator
{
public Prouct factory();
}
public SubCreator1 implent Creator
{
public Prouct factory()
{
return new ConcreteProduct1();
}
}
public SubCreator2 implent Creator
{
public Prouct factory()
{
return new ConcreteProduct2();
}
}
请注意:返回类型是Product型的!!
这样客户端调用是直接new 一个具体工厂的实例,然后命令它去生产,而对于具体工厂的父类(既工厂接口,接口完全可以改成子类继承父类来实现,只是这样不好,不符合OO的原则),它完全不知道什么产品被生产了,甚至它连那个具体工厂被实例化它都不知道
抽象工厂模式
抽象工厂模式主要是用来解决具体产品是有几类产品簇的问题
public interface Creator
{
public ProuctA factoryA();
public ProuctB factoryB();
}
public interface ProductA //ProductA 接口
{
}
public interface ProductB //ProductB 接口
{
}
public class ConCreator1 implent Creator
{
public ProuctA factoryA()
{
return new ConcreteProductA1();
}
public ProuctB factoryB()
{
return new ConcreteProductB1();
}
}
public class ConCreator2 implent Creator
{
public ProuctA factoryA()
{
return new ProductA2();
}
public ProuctB factoryB()
{
return new ProductB2();
}
}
public class ProductA1 implements ProductA
{
public ProductA1()
{
}
}
public class ProductA2 implements ProductA
{
public ProductA2()
{
}
}
public class ProductB1 implements ProductB
{
public ProductB1()
{
}
}
public class ProductB2 implements ProductB
{
public ProductB2()
{
}
}
实际上是这样的
1,两个工厂类ConCreator1,ConCreator2都实现了Creator接口
2,ProuctA1,ProductA2都实现了ProductA接口
3,ProuctB1,ProductB2都实现了ProductB接口
4,ConCreator1负责生产ProductA类型的产品(包括ProductA1,ProductB1)
5,ConCreator2负责生产ProductB类型的产品(包括ProductA2,ProductB2)
6,工厂方法也有这样的特征,也就是说Creator不知道什么被生产出来,甚至不知道ConCreator1还是ConCreator2被实例化了,因为client高兴调那一个工厂,就调那一个工厂,就是说工厂能生产什么,对客户端是可见的。甚至还有一种情况,客户端高兴起来就生产了ProductA1,我就不生产ProductA2,因为上面的例子中它们还都是松散的,没有绑定在一起
于是提出另外一个例子,也是老提起的电脑类型的例子
1,电脑生产商是接口,
2,CUP是接口,
3,硬盘是接口,
4,IBM工厂是制造IBM品牌的电脑的工厂
5,DELL工厂是制造DEll品牌的电脑的工厂
为讨论方便,就认为电脑=CUP+硬盘;
6,所以呀CUP有IBM的CPU和DELL的CPU
7,同样硬盘也是有IBM的硬盘和DELL的硬盘
8,IBM工厂生产IBM的CPU和IBM的硬盘,绝对不生产DELL的CPU,也不生产DELL的硬盘
9,同样DELL工厂也是一样
public interface 电脑生产商
{
public CPU 制造CPU();
public 硬盘 制造硬盘();
}
public interface CPU
{
}
public interface 硬盘
{
}
public class IBM的CPU implements CPU
{
public IBM的CPU();
}
public class IBM的硬盘 implements 硬盘
{
public IBM的硬盘();
}
public class DELL的CPU implements CPU
{
public DELL的CPU();
}
public class DELL的硬盘 implements 硬盘
{
public DELL的硬盘();
}
//下面是IBM工厂
public class IBM工厂
{
private CPU IBM的CPU私有变量=null;
private 硬盘 IBM的硬盘私有变量=null;
private CPU 制造IBMCPU()
{
return new IBM的CPU();
}
private 硬盘 制造IBM硬盘()
{
return new IBM的CPU();
}
public 电脑 制造IBM电脑()
{
try{
IBM的CPU私有变量=制造IBMCPU();
IBM的硬盘私有变量=制造IBM硬盘();
if(IBM的CPU私有变量!=null&&IBM的硬盘私有变量!=null)
retrun (IBM的CPU私有变量+IBM的硬盘私有变量);
//组装成IBM电脑
}
catch(Exception e)
{
System.out.println("制造IBM电脑失败!");
}
}
}
}
这样,客户端无法通过命令单生产出一个CPU来,这样抽象才真正成为一个完整产品的工厂,只要向工厂发出生产的命令,一台完整的电脑就生产出来了,而工厂怎么生产的,生产了哪些部件,外界就看不见了,外界就知道这个工厂是生产IBM电脑整机的工厂!
DELL电脑工厂一样
Abstract Factory:谢谢,请记住我,抽象工厂,在下面情况下请记住及时使用我:
- 一个系统要独立于它的产品的创建、组合和表示时。
- 一个系统要由多个产品系列中的一个来配置时。
- 当你要强调一系列相关的产品对象的设计以便进行联合使用时。
- 当你提供一个产品类库,而只想显示它们的接口而不是实现时。
Factory Method:我是工厂方法,遇到下面情况,不要犹豫地使用我:
- 当一个类不知道它所必须创建的对象的类的时候。
- 当一个类希望由它的子类来指定它所创建的对象的时候。
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信 息局部化的时候。
转自:http://hi.baidu.com/xulin_1027/blog/item/30ff9c1ee4ef791c413417d0.html