设计模式之FactoryMethod模式

设计模式之FactoryMethod模式

FactoryMethod模式属于23种设计模式中的创建型模式,解决的是如何“new”的问题。

引例:
还是先从简单的例子入手FactoryMethod模式吧,现在需要一个汽车测试的环境来对汽车进行测试,我们很容易会这样设计
 1 /**/ //////////////////////////////////////////////
 2 // 汽车类
 3 class  Car
 4 {
 5public:
 6    void Startup(){}
 7    void Run() {}
 8    void Turn() {}
 9    void Stop() {}
10}
;
11
12 /**/ //////////////////////////////////////////////
13 // 汽车测试环境
14 class  CarTestFramework
15 {
16public:
17    void DoTest()
18    {
19        Car* car = new Car();
20        car->Startup();
21        car->Run();
22        car->Turn();
23        car->Stop();
24    }

25}
;


非常简单的设计,但是存在问题,如果我们要对红旗车,东风车进行测试,那么怎么办?
有了之前那些模式的经验,再回想下面向对象的特性。。。
“多态”!将Car设计成为一个抽象类,DoTest里全部使用抽象类的指针来操作,那不就可以应对不同类型的汽车了吗?
于是有了以下的代码:(注意DoTest的参数,这样使用才可以让用户指定车辆的类型)
/**/ //////////////////////////////////////////////
// 抽象汽车类
class  AbstractCar
{
public:
    
virtual void Startup() = 0;
    
virtual void Run() = 0;
    
virtual void Turn() = 0;
    
virtual void Stop() =0;
}
;

/**/ //////////////////////////////////////////////
// 具体汽车类——红旗车
class  HongqiCar :  public  AbstractCar
{
public:
//具体实现抽象汽车类的四个方法.
}
;

/**/ //////////////////////////////////////////////
// 汽车测试环境
class  CarTestFramework
{
public:
    
void DoTest(AbstractCar* car)
    
{
        car
->Startup();
        car
->Run();
        car
->Turn();
        car
->Stop();
    }

}
;


到此为止的设计其实还是不错的,能够应对不同类型的汽车变化,如果增加了新的汽车类型也完全不用修改现有代码,只需要增加代码就可以了
但如果测试车辆不止一辆怎么办?以上设计的缺陷就在于DoTest的参数,参数的个数对应于测试车辆的数量,测试数量不确定是很正常的事情。
再想想面向对象有什么特性。。。“封装”!用一个类专门用来封装汽车的创建就搞定这个问题了嘛!这个类起个特别的名字就是“工厂类”。

动机:
软件系统中,我们经常面对“某个对象”的创建工作;由于需求的变化,这个对象经常面临剧烈的变化,但他有相对稳定的接口。
为了抵抗这种变化,提出“封装变化点”的思想,采用“封装”机制将其“变化部分”隔离出来,从而保证“其他依赖该对象的对象”不随需求变化而变化。

意图:
定义一个用于创建对象的接口,让子类决定实例化哪个类。Factory Method使得一个类的实例化延迟到子类。(GoF23)

设计思路:
还是先看看UML图
设计模式之FactoryMethod模式_第1张图片
如果只看左边的Product和ConcreteProduct部分,那么这就是我们的第2种设计方案。
FatoryMethod在Product和ConcreteProduct的基础上加上了Creator和ConcreteCreator,分别就是Factory和ConcreteFactory。Factory有个非常重要的函数CreateProduct()(就是图中的AnOperation),它将对象的创建工作封装了起来。

总结:
1.OO的“多态”。大部分的设计模式都会体现出OO的这个原则,他的作用就是“推迟实现”,将一个类的实例化推迟到子类,从而解决不同类型对象的创建问题。
2.OO的“封装”。工厂方法另一个重要思想,工厂类把创建工作封装起来,这样用户就可以多次使用,解决了同时创建多个对象的问题。
3.工厂方法和抽象工厂的区别:其实抽象工厂模式可以看作工厂模式的一个特例。工厂模式在工厂类中只创建一种类型的对象,如果在工厂类中拥有创建多种类型的对象的方法(比如创建引擎,创建车门,创建车灯。。。)那其实不就是之前讨论的抽象工厂模式嘛?
4.当我们创建一系列有继承关系的类时都可以考虑使用工厂方法。回想之前项目中使用的Ogre,工厂方法使用非常广泛,几乎所有对象都不是new出来的,Ogre提供了许许多多的CreateXX方法。

自己做的示例代码,仅供参考:
AbstractFactory.h
1 #pragma once
2 #include  " AbstractCar.h "
3
4 class  AbstractCarFactory
5 {
6public:
7    virtual AbstractCar* CreateCar() = 0;
8}
;
AbstractCar.h
 1 #pragma once
 2
 3 class  AbstractCar
 4 {
 5public:
 6    virtual void Startup() = 0;
 7    virtual void Run() = 0;
 8    virtual void Turn() = 0;
 9    virtual void Stop() = 0;
10}
;
11
HongqiCarFactory.h
 1 #pragma once
 2 #include  " AbstractCarFactory.h "
 3 #include  " HongqiCar.h "
 4
 5 class  HongqiCarFactory : public  AbstractCarFactory
 6 {
 7public:
 8    virtual AbstractCar* CreateCar()
 9    {
10        return new HongqiCar();
11    }

12}
;
13
HongqiCar.h
 1 #pragma once
 2 #include  " AbstractCar.h "
 3 #include  < iostream >
 4 using   namespace  std;
 5
 6 class  HongqiCar :  public  AbstractCar
 7 {
 8public:
 9    virtual void Startup()
10    {
11        cout<<"HongqiCar : Startup()"<<endl;
12    }

13    virtual void Run()
14    {
15        cout<<"HongqiCar : Run()"<<endl;
16    }

17    virtual void Turn()
18    {
19        cout<<"HongqiCar : Turn()"<<endl;
20    }

21    virtual void Stop()
22    {
23        cout<<"HongqiCar : Stop()"<<endl;
24    }

25}
;
26
Main.cpp
 1 /**/ //////////////////////////////////////////////////////////////////////////
 2 //  FactoryMethodTest for Factory Method Test
 3 /**/ //////////////////////////////////////////////////////////////////////////
 4
 5 #include  " stdafx.h "
 6 #include  " AbstractCar.h "
 7 #include  " AbstractCarFactory.h "
 8 #include  " HongqiCar.h "
 9 #include  " HongqiCarFactory.h "
10 #include  < iostream >
11 using   namespace  std;
12
13
14 class  CarTestFramework
15 {
16public:
17    void DoTest(AbstractCarFactory* carFactory)
18    {
19        AbstractCar* car1 = carFactory->CreateCar();
20        cout<<"//////////////////////////////////////////////\n//Car1 Test\n//////////////////////////////////////////////"<<endl;
21        car1->Startup();
22        car1->Run();
23        car1->Turn();
24        car1->Stop();
25
26        AbstractCar* car2 = carFactory->CreateCar();
27        cout<<"\n//////////////////////////////////////////////\n//Car2 Test\n//////////////////////////////////////////////"<<endl;
28        car2->Startup();
29        car2->Run();
30        car2->Turn();
31        car2->Stop();
32    }

33}
;
34
35
36 int  _tmain( int  argc, _TCHAR *  argv[])
37 {
38    CarTestFramework* carTestFramework = new CarTestFramework();
39    cout<<"Test the HongqiCar"<<endl;
40    carTestFramework->DoTest(new HongqiCarFactory());
41
42    return 0;
43}

44
45

你可能感兴趣的:(设计模式之FactoryMethod模式)