设计模式(1)-工厂方法(Factory Method)

原创 2006年05月24日 17:48:00
一. 工厂方法(factory-method)模式
 
1.意图

定义一个创建对象的接口,让子类决定实例化哪个产品类。工厂方法使一个对象的创建延迟到子类。

 
2.适用性

当一个类不知道它要创建的对象的类时。

当一个类希望由它的子类来决定创建哪个类的对象时。

当一个类决定将创建对象委托给多个子类,并且希望将那个子类是代理这一信息局部化的时候。

 

3.结构
 
   
4.参与者

     Creater

声明工厂方法的抽象类,工厂方法返回一个产品类(Product)。

可以调用工厂方法返回一个产品对象。

 

   ConcreteCreater

重定义工厂方法,以返回一个特定的product

 

   Product:

产品抽象类,给用户提供一致的产品接口。

 

  ConcreteProduct:

特定的产品,实现product接口。

 
5.效果

工厂方法将特定的类的实例化延迟到子类,而且返回product接口,使用户代码不用和具体类打交道,一致的对待Product。所以在用户要加入新产品的时候,无需更改客户代码,只需加入一个新的ConcreteProductConcreteCreater即可,这个也是遵 守了“开放封闭原则”。

       连接平行的类层次,上面的结构图中,ConcreteCreater1对应创建ConcreterProduct1ConcreteCreater2对应创建ConcreterProduct2。所以createrproduct的类层次是平行的,用户只需选定一个Creater,就创建出对应的product。像是一个map一样,不会出现牛头不对马嘴之态。

 

6.实现及变体

   Creater有两种实现,一种就是抽象的工厂方法,具体实现留到子类。另一种就是有一个缺省的实现,子类也可以重新实现这个方法。这种方法使用于真的有一个默认的Product需要实例化的这种情况

  带参数的工厂方法,这种情况可以创建多种产品,不过有个限制就是所有产品都要实现product接口,否则就失去工厂方法的意义了。代码如下:

 

Product*  ConcreteCreater1::FactoryMethod(int nID)
{
     If(nID ==  BUTTON)
     {
         return new button;
}
Else if(nID ==  BOX)
{
    return new box; 
}
}
 

用模板实现,省略创建子类。

 

class Creater

{

public:

     virtual Product* FactoryMethod() = 0;

};

 

template<class theProduct>

class TempCreater: public Creater

{

     virtual Product* FactoryMethod();

};

 

 

template<class theProduct>

Product* TempCreater<theProduct>::FactoryMethod()

{

     return new theProduct;

}

 

 使用这个模版客户端只需定义产品,而不需定义creater的子类。

 

 
 
 
二. 程序举例

   在一个ACT游戏中,主角过关过程中有许多敌人,如狼(wolf,蝙蝠(bat,老怪(BOSS,在每一关的刚开始就要创建许多不同的敌人,如果不用工厂方法,则把所有的创建任务都放在了客户代码中,则一个代码不易扩充和修改,二是代码很杂乱。而用了工厂方法则可以克服这两个缺点。比如你增加一个新的敌人-恐龙,则只需增加一个恐龙类(ConcreteProduct),再增加一个创建恐龙的类(ConcreteCreater )就OK了。

源码如下:
         //product abstract class
 
class Enemy
{
public:
       virtual void attack() = 0;
       virtual void Draw() = 0;
       virtual ~Enemy() = 0;
};
 
// concrete product class
class Wolf : public Enemy
{
       void attack()
       {
              cout << "Wolf attack me!" << endl;
       }
       void Draw()
       {
              cout << "I am Wolf!" << endl;
       }
};
 
// concrete product class
class Bat : public Enemy
{
       void attack()
       {
              cout << "Bat attack me!" << endl;
       }
       void Draw()
       {
              cout << "I am Bat!" << endl;
       }
};
 
// concrete product class
class Boss : public Enemy
{
       void attack()
       {
              cout << "Boss attack me!" << endl;
       }
       void Draw()
       {
              cout << "I am Boss!" << endl;
 
      }
};
 
// creater abstract class
class EnemyCreater
{
       virtual Enemy* CreateEnemy() = 0;
};
 
// concrete creater class
class WolfCreater : public EnemyCreater
{
        Enemy* CreateEnemy()
        {
               return new Wolf;
        }
};
 
// concrete creater class
class BatCreater : public EnemyCreater
{
        Enemy* CreateEnemy()
        {
               return new Bat;
        }
};
 
// concrete creater class
class BossCreater : public EnemyCreater
{
        Enemy* CreateEnemy()
        {
               return new Boss;
        }
};
 
 
int main(int argc, char* argv[])
{
       EnemyCreater* enemyCreater[3];
    enemyCreater[0] = new WolfCreater;
    enemyCreater[1] = new BatCreater;
       enemyCreater[2] = new BossCreater;
       Enemy* cruEnemy = NULL;
       for(int i = 0; i < 3; ++i)
       {
              cruEnemy = enemyCreater[i].CreateEnemy();
              
              cruEnemy->Draw();
              cruEnemy->attack();
 
              delete cruEnemy;
       }
       return 0;
}
 
三. 相关模式

Abstract Factory经常用工厂方法来实现。

工厂方法通常在Template Methods中被调用。
Prototypes不需要创建Creater的子类。但是,它们通常要求一个针对Product类的Initialize操作。Creater使用Initialize来初始化对象。而Factory Method不需要这样的操作
 
 
四. 参考文献
 
《设计模式精解》清华大学出版社,熊杰译。
      《设计模式可复用面向对象软件的基础》机械工业出版社,四人团著。

我所理解的设计模式(C++实现)——工厂方法模式(Factory Method Pattern)

工厂方法模式不同于简单工厂模式的地方在于工厂方法模式把对象的创建过程放到里子类里。这样工厂父对象和产品父对象一样,可以是抽象类或者接口,只定义相应的规范或操作,不涉及具体的创建或实现细节。  其...
  • tanningzhong
  • tanningzhong
  • 2015年01月24日 14:51
  • 587

java学习:log4j输出xml格式的日志文件(log4j2篇)

上一篇讲解了log4j输出xml格式的日志文件,本篇讲述log4j2.x版本。log4j2.x版本相比log4j1变化很大,使用起来也更麻烦,主要是jar包的依赖的问题。先上代码,然后再列举遇到的问题...
  • KiteRunner
  • KiteRunner
  • 2016年07月16日 23:59
  • 5226

设计模式总结之Factory Method Pattern(工厂方法模式)

定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。...
  • cooldragon
  • cooldragon
  • 2016年08月11日 00:44
  • 1118

Factory Method模式的误区:Factory Method模式是简化版的Abstract Factory吗?

happyhippy作者:Silent Void  出处:http://happyhippy.cnblogs.com/ 转载须保留此声明,并注明在文章起始位置给出原文链接。   转载地址...
  • luonan0706
  • luonan0706
  • 2015年05月09日 11:52
  • 361

Factory Method模式的误区:Factory Method模式是简化版的Abstract Factory吗?

FactoryMethod是一个相对比较简单的创建型模式,但是能领悟或者用对的并不多见;很多示例都没有反应出Factory Method的核心思想,只是实现了一个简化版的Abstract Factor...
  • ycl295644
  • ycl295644
  • 2015年07月10日 13:22
  • 335

struts2的关于method=“{1}"意思详解

struts2的关于method=“{1}"意思详解        中Login_*带*是什么意思?method= "{1} "带{}这个是什么意思?    ==================...
  • syy0377
  • syy0377
  • 2014年03月10日 16:29
  • 1612

1、工厂方法模式(Factory Method)

1、工厂方法模式(Factory Method) 工厂方法模式分为三种: 11、普通工厂模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。首先看下关系图: 举例如下:(我们举一个发送...
  • mixiu888
  • mixiu888
  • 2017年12月12日 08:08
  • 34

1、工厂方法模式(Factory Method)

工厂方法模式工厂方法模式分为三种: 1、普通工厂模式就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。 2、多个工厂方法模式,是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字符...
  • Half_open
  • Half_open
  • 2016年10月13日 22:45
  • 7400

Cas(06)-基于数据库的认证

Cas Server自身已经为我们实现了几种基于JDBC的AuthenticationHandler实现,但它们不包含在Cas Server的核心包里面,而是包含在cas-server-support...
  • zmx729618
  • zmx729618
  • 2016年05月25日 14:04
  • 505

工厂方法(Factory Method)

前言:工厂方法模式通过抽象工厂类约定了一个创建对象的接口,并由抽象工厂的子类决定实际生产的对象。 栗子场景描述一家企业特别热衷于生产事物,就通过抽象类的形式(FoodFactory)约定了将来子孙创建...
  • dufengx
  • dufengx
  • 2016年10月26日 21:54
  • 78
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:设计模式(1)-工厂方法(Factory Method)
举报原因:
原因补充:

(最多只允许输入30个字)