您的位置:首页 > 其它

设计模式之(一)工厂模式Factory

2011-08-03 11:01 459 查看
在软件系统中,经常面临着“某个对象”由于需求的变化,对象的具体实现面临着剧烈的变化。为了应对这种变化我们抽象出它比较稳定的接口,隔离出“这个易变对象”的变化,从而保持系统中“其它依赖该对象的对象”不随着需求的改变而改变,这就是要说的Factory Method模式了。

定义一个用户创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。

简单工厂:





例子:如果生活中有两种灯一种是灯泡,另一种是灯管,它们都有两个方法TurnOn()和TurnOff(),有两个人,一个人会做灯泡,一个人会做灯管,他们两个各自做各自的。 如果我要订两批灯一批是灯泡一批是灯管的话。那我要分别派人去找两个人分别谈判、沟通两次,再分别派人取货,但有一天我派去取货的人喝醉了,去做灯泡的人那里去要灯管,又去做灯管的人那里取灯泡,这样可就出错了。后来这两个人合做开了一家灯工厂,拥有两条生产线,这个工厂能同时造灯泡和灯管,那我只需与这家工厂谈判一次就可以了,也只需派人来这个工厂的销售部取货就可以了。当然销售部不能只销售灯泡,也不能只销售灯管,是二者都销售,根据订单不同销售的内容也不同。

using System;
public abstract class Light
{
public abstract void TurnOn();
public abstract void TurnOff();
}
public class BulbLight : Light
{
public override void TurnOn()
{
Console.WriteLine("Bulb Light is Turned on");
}
public override void TurnOff()
{
Console.WriteLine("Bulb Light is Turned off");
}
}
public class TubeLight : Light
{
public override void TurnOn()
{
Console.WriteLine("Tube Light is Turned on");
}
public override void TurnOff()
{
Console.WriteLine("Tube Light is Turned off");
}
}
public class LightSimpleFactory
{
public Light Create(string LightType)
{
if(LightType == "Bulb")
return new BulbLight();
else if(LightType == "Tube")
return new TubeLight();
else
return null;
}
}
public class Client
{
public static void Main()
{
LightSimpleFactory lsf = new LightSimpleFactory();
Light l = lsf.Create("Bulb");
l.TurnOn();
l.TurnOff();
Console.WriteLine("-----------------");
l = lsf.Create("Tube");
l.TurnOn();
l.TurnOff();
}
}


工厂类角色Creator (LightSimpleFactory)工厂类在客户端的直接控制下(Create方法)创建产品对象。
抽象产品角色Product (Light)定义简单工厂创建的对象的父类或它们共同拥有的接口。可以是一个类、抽象类或接口。
具体产品角色ConcreteProduct (BulbLight, TubeLight)定义工厂具体加工出的对象。

优点:
工厂类可以决定创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅"消费"产品。实现了对责任的分割。

缺点:

工厂类集中了所有产品创建逻辑,一旦工厂不能正常工作,整个系统都要受到影响。

系统扩展困难,一旦添加新产品就不得不修改工厂逻辑(生产线)。

复杂工厂:

在第二种工厂中核心工厂不再负责所有产品的创建,而是将具体创建工作交给子类去做。核心工厂仅仅负责给出具体工厂必须实现的接口,而不接触某一个产品类被实例化这种细节。这可以在引进新产品的时候增加一个新的具体工厂就可以了,而不用去大改现有的工厂。



在第二种工厂中,工厂类与产品类往往具有平行的等级结构,它们之间一一对应。

例子:如果上面例子中要生产一种新产品-探照灯,那就得把原来的两条生产线进行大的修改,生产完成后再把生产线改回来,这样就太影响工作了,于是他们想出了一个方法再建一条生产线,专门生产探照灯。

using System;
public abstract   class Light
{
public abstract void TurnOn();
public abstract void TurnOff();
}
public class BulbLight : Light
{
public override void TurnOn()
{ Console.WriteLine("Bulb Light is Turned on"); }
public override void TurnOff()
{ Console.WriteLine("Bulb Light is Turned off"); }
}
public class TubeLight : Light
{
public override void TurnOn()
{ Console.WriteLine("Tube Light is Turned on"); }
public override void TurnOff()
{ Console.WriteLine("Tube Light is Turned off"); }
}
public abstract   class Creator
{
public abstract Light factory();
}
public class BulbCreator : Creator
{
public override Light factory()
{ return new BulbLight(); }
}
public class TubeCreator : Creator
{
public override Light factory()
{ return new TubeLight(); }
}
public class Client
{
public static void Main()
{
Creator c1 = new BulbCreator();
Creator c2 = new TubeCreator();
Light l1 = c1.factory();
Light l2 = c2.factory();
l1.TurnOn();
l1.TurnOff();
Console.WriteLine("-----------------");
l2.TurnOn();
l2.TurnOff();
}
}


抽象工厂(Creator)角色:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。

具体工厂(Concrete Creator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。在上图中有两个这样的角色:BulbCreator与TubeCreator。

抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。在上图中,这个角色是Light。

具体产品(Concrete Product)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。

以上转自http://hi.baidu.com/grayworm/blog/item/4a832160f8c9de46eaf8f8c1.html

关于抽象工厂,还有一个比较好的例子:



在这张图中, 有两类产品接口interface RAM 和interface CPU; 同时有两个创建方法:MacProducer 和PCProducer,这两个创建方法中都有createCPU()和createRAM(),返回的实例对象组是CPU 和RAM, 这是分别来自两类产品接口,但是是一种对应,彼此是相关的.因此它是抽象工厂.

它有个特点,就是通常工厂的类层次与产品的类层次几乎是一样的树。抽象工厂模式是让工厂和依赖工厂的子类全部依赖一个接口或者抽象类,因为抽象代表这稳定,这样可以很容易的遵循oo中比较著名的开放关闭原则,设计出来的系统、框架或者程序很富有弹性和扩展能力。

GOF 的Design pattern 里对Factory Pattern 是这么写的 

Use the Factory Method pattern when 

1. a class can't anticipate the class of objects it must create. 

2. a class wants its subclasses to specify the objects it creates. 

3. classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate.

factory pattern更多是用在几个接口与他们各自依赖于RUNTIME TYPE的子类所构成的体系, 在Template method 里也有运用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息