您的位置:首页 > 其它

设计模式之-工厂方法模式(学习分析笔记)

2011-07-30 12:14 495 查看
分析原则:封装变化,解耦

FACTORY METHOD(工厂方法)—对象创建型模式
1. 意图

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

解读:之前在讨论抽象工厂模式的时候已经引出过工厂方法模式了。这里再简单的提一下,就是设想有这种情况。

你有个项目,有对象A、B、C...需要在很多地方创建对象,那么类似A *a = new A(); B *b = new B();C *c = new C();这样的代码就会随处可见,如果需求变化,

可能要对这些创建对象进行修改,那么就会相当麻烦,而且不好管理。也就是对象的创建是变化点,那么我们就需要封装变化。可能你想到了 简单工厂模式,但是简单工厂模式不能满足OCP原则(开放封闭原则:对扩展开放,对修改关闭)。因此出现了工厂方法模式,工厂方法模式是简单工厂模式的衍生,完全实现‘开-闭 原则’,实现了可扩展。

2. 适用性

在下列情况下可以使用Factory Method模式:

• 当一个类不知道它所必须创建的对象的类的时候。

• 当一个类希望由它的子类来指定它所创建的对象的时候。

• 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。

3. 结 构

 



4. 参与者

• P r o d u c t

— 定义工厂方法所创建的对象的接口。

• C o n c r e t e P r o d u c t

— 实现P r o d u c t接口。

• C r e a t o r

— 声明工厂方法,该方法返回一个 P r o d u c t类型的对象。C r e a t o r也可以定义一个工厂方

法的缺省实现,它返回一个缺省的C o n c r e t e P r o d u c t对象。

— 可以调用工厂方法以创建一个P r o d u c t对象。

• C o n c r e t e C r e a t o r

— 重定义工厂方法以返回一个C o n c r e t e P r o d u c t实例。

工厂方法的一个潜在缺点在于客户可能仅仅为了创建一个特定的 C o n c r e t e P r o d u c t对象,就不得不创建C r e a t o r的子类。

5. 实 现

当应用Factory Method模式时要考虑下面一些问题:

1 ) 主要有两种不同的情况 Factory Method模式主要有两种不同的情况: 1)第一种情况是,C r e a t o r类是一个抽象类并且不提供它所声明的工厂方法的实现。 2)第二种情况是,C r e a t o r是一个具体的类而且为工厂方法提供一个缺省的实现。也有可能有一个定义了缺省实现的抽象类,但这不太常见。第一种情况需要子类来定义实现,因为没有合理的缺省实现。它避免了不得不实例化不可预见类的问题。在第二种情况中,具体的 C r e a t o r主要因为灵活性才使用工厂方法。它所遵循的准则是,
“用一个独立的操作创建对象,这样子类才能重定义它们的创建方式。 ”这条准则保证了子类的设计者能够在必要的时候改变父类所实例化的对象的类。

2 ) 参数化工厂方法 该模式的另一种情况使得工厂方法可以创建多种产品。工厂方法采用一个标识要被创建的对象种类的参数。工厂方法创建的所有对象将共享 P r o d u c t接口。

一个参数化的工厂方法具有如下的一般形式,此处 M y P r o d u c t和Yo u r P r o d u c t是P r o d u c t的子类:

class Creator
{
public:
virtual Product* Creat(ProductId);
};

Product* Creator::Creatr(ProductId id)
{
if(id == MINE) return new MyProduct();
if(id == YOURS) return new YourProduct;

return 0;
}

在我参与的项目中,就是利用了工厂方法模式来创建所需对象的。

3 ) 使用模板以避免创建子类 正如我们已经提及的,工厂方法另一个潜在的问题是它们可能仅为了创建适当的P r o d u c t对象而迫使你创建C r e a t o r子类。在C + +中另一个解决方法是提供C r e a t o r的一个模板子类,它使用P r o d u c t类作为模板参数:



示例代码:

class MobileFactory
{
public:
virtual Mobile* produceMobile() = 0;
}

class Mobile
{
public:
virtual void call() = 0;
}

class MotorolaFactory :public MobileFactory
{
public:
Mobile* produceMobile()
{
return new Motorola();
}
}

class Nokia :public Mobile
{
public:
void call()
{
printf("Nokia producted");
}
}

客户端使用时:

MobileFactory *mbf = new NokiaFactory();
Mobile *mb=mbf->produceMobile();
mb->call();
mbf = new MotorolaFactory();
mb = mbf->produceMobile();
mb->call();


6. 相关模式

Abstract Factory经常用工厂方法来实现。工厂方法通常在Template Methods中被调用。P r o t o t y p e s不需要创建C r e a t o r的子类。但是,它们通常要求一个针对 P r o d u c t类的I n i t i a l i z e操作。C r e a t o r使用I n i t i a l i z e来初始化对象。而Factory Method不需要这样的操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息