问题:
在面向对象系统设计中经常可以遇到以下的两类问题:
问题1
为了提高内聚(Cohesion) 和松耦合(Coupling),需要我们抽象出一些类的公共接口以形成抽象基类或者接口。这样我们可以通过声明一个基类的指针指向子类对象进而达到多态的目的,但是这样很容易出现一个问题:n多的子类继承自抽象基类,我们不得不在每次要用到子类的地方就编写new xxx();这样就有两个问题产生:
- 必须要有实际子类的名称(命名困难,可读性和可记忆性都不友好)
- 程序的扩展性和维护变得困难
问题2
还有一种情况就是在父类中并不知道具体要实例化哪一个具体的子类。意思是:假如类B是一个抽象父类,A是一个类,现在我们在类 A 中要使用到类 B,但是在 A 中并不知道具体要实例化哪一个 B 的子类,但是在类 A 的子类 D 中是可以知道的,在 A 中我们没有办法直接使用类似于 new xxx()的语句,因为根本就不知道xxx是什么。
以上两个问题也就引出了 Factory 模式的两个最重要的功能:
- 定义创建对象的接口,封装了对象的创建;
- 使得具体化类的工作延迟到了子类中。
模式选择:
- 在第一个问题中,我们经常就是声明一个创建对象的接口,并封装了对象的创建过程。Factory 这里类似于一个真正意义上的工厂(生产对象)。
- 在第二个问题中,我们需要提供一个对象创建对象的接口,并在子类中提供其具体实现(因为只有在子类中可以决定到底实例化哪一个类)。
Factory 的结构示意图1
图 1 所以的 Factory 模式经常在系统开发中用到,但是这并不是 Factory 模式的最大威力所在(因为这可以通过其他方式解决这个问题)。Factory 模式不单是提供了创建对象的接口,其最重要的是延迟了子类的实例化(第二个问题),以下是这种情况的一个Factory 的结构示意图:
Factory 模式结构示意图 2
图 2 中关键中 Factory 模式的应用并不是只是为了封装对象的创建,而是要把对象的创建放到子类中实现,Factory 中只是提供了对象创建的接口,其实现将放在 Factory 的子类ConcreteFactory 中进行。这是图 2 和图 1 的区别所在。
实现
Product.h
#ifndef PRODUCT_H
#define PRODUCT_H
enum ELECTRONICSPRODUCT
{
PHONE,
COMPUTER,
PRINTER,
};
enum FRUITPRODUCT
{
APPLE,
BANANA,
SNOWPEAR,
};
//产品父类
class Product
{
public:
virtual ~Product();
virtual void showWhatProduct() = 0;
Product();
};
//电子产品父类
class ElectronicsProduct:public Product
{
public:
virtual void showWhatProduct();
};
//电话--->电子产品
class Phone:public ElectronicsProduct
{
public:
void showWhatProduct();
};
//电脑--->电子产品
class Computer:public ElectronicsProduct
{
public:
void showWhatProduct();
};
//打印机--->电子产品
class Printer:public ElectronicsProduct
{
public:
void showWhatProduct();
};
/*************************************************************/
//水果父类
class FruitProduct:public Product
{
public:
void showWhatProduct();
};
//苹果------>水果类
class Apple:public FruitProduct
{
public:
void showWhatProduct();
};
//香蕉------>水果类
class Banana:public FruitProduct
{
public:
void showWhatProduct();
};
//雪梨------>水果类
class SnowPear:public FruitProduct
{
public:
void showWhatProduct();
};
#endif // PRODUCT_H
Product.cpp
#include "product.h"
#include <iostream>
using namespace std;
void Product::showWhatProduct()
{
cout<<"Product"<<endl;
}
Product::Product()
{
cout<<"CreateProduct"<<endl;
}
Product::~Product()
{
cout<<"DestoryProduct"<<endl;
}
void Phone::showWhatProduct()
{
cout<<"this is a Phone...."<<endl;
}
void Computer::showWhatProduct()
{
cout<<"this is a Computer"<<endl;
}
void Printer::showWhatProduct()
{
cout<<"this is a Printer"<<endl;
}
void Apple::showWhatProduct()
{
cout<<"this is a Apple"<<endl;
}
void Banana::showWhatProduct()
{
cout<<"this is a Banana"<<endl;
}
void SnowPear::showWhatProduct()
{
cout<<"this is a SnowPear"<<endl;
}
void FruitProduct::showWhatProduct()
{
cout<<"this is a FruitProduct"<<endl;
}
void ElectronicsProduct::showWhatProduct()
{
cout<<"this is a ElectronicsProduct"<<endl;
}
factory.h
#ifndef FACTORY_H
#define FACTORY_H
#include "product.h"
enum FACTORY
{
ELECTRONICSFACTORY,//电子厂
FRUITFACTORY,//水果加工厂
};
class Factory
{
public:
virtual ~Factory();
Factory();
virtual Product *CreateProduct(int mode) = 0;
};
//建筑队-->专门生产工厂的
class ConcreteFactory
{
public:
Factory *createdFactory(int factoryMode);
};
//电子工厂类-->该工厂专门生产电子产品
class ElectronicsFactory:public Factory
{
public:
~ElectronicsFactory();
ElectronicsFactory();
Product *CreateProduct(int mode);
};
//水果工厂类-->该工厂专门生存水果产品
class FruitFactory:public Factory
{
public:
~FruitFactory();
FruitFactory();
Product *CreateProduct(int mode);
};
#endif // FACTORY_H
factory.cpp
#include "factory.h"
#include <iostream>
using namespace std;
Factory::Factory()
{
cout<<"CreatedFactory..."<<endl;
}
Factory::~Factory()
{
cout<<"DestoryFactory..."<<endl;
}
ElectronicsFactory::ElectronicsFactory()
{
cout<<"ElectronicsFactory..."<<endl;
}
ElectronicsFactory::~ElectronicsFactory()
{
cout<<"~ElectronicsFactory..."<<endl;
}
Product *ElectronicsFactory::CreateProduct(int mode)
{
ElectronicsProduct *product;
switch (mode)
{
case PHONE:
product = new Phone();
break;
case COMPUTER:
product = new Computer();
break;
case PRINTER:
product = new Printer();
break;
default:
product = nullptr;
break;
}
return product;
}
FruitFactory::~FruitFactory()
{
cout<<"~FruitFactory"<<endl;
}
FruitFactory::FruitFactory()
{
cout<<"FruitFactory"<<endl;
}
Product *FruitFactory::CreateProduct(int mode)
{
FruitProduct *product;
switch (mode)
{
case APPLE:
product = new Apple();
break;
case BANANA:
product = new Banana();
break;
case SNOWPEAR:
product = new SnowPear();
break;
default:
product = nullptr;
break;
}
return product;
}
Factory *ConcreteFactory::createdFactory(int factoryMode)
{
Factory *factory;
switch (factoryMode)
{
case ELECTRONICSFACTORY:
factory = new ElectronicsFactory();
break;
case FRUITFACTORY:
factory = new FruitFactory();
break;
default:
factory = nullptr;
break;
}
return factory;
}
main.cpp
#include <iostream>
#include "product.h"
#include "factory.h"
using namespace std;
void test()
{
ConcreteFactory *f = new ConcreteFactory();//相当于建筑队
Factory *f1 = f->createdFactory(ELECTRONICSFACTORY);//打造该工厂类型是电子厂
Product *p1 = f1->CreateProduct(PHONE);//工厂生产产品
p1->showWhatProduct();//生产的是手机
cout<<"-------------------"<<endl;
Factory *f2 = f->createdFactory(FRUITFACTORY);//打造该工厂类型是水果加工厂
Product *p2 = f2->CreateProduct(SNOWPEAR);//工厂加工产品
Product *p3 = f2->CreateProduct(APPLE);
p2->showWhatProduct();//加工的是苹果
p3->showWhatProduct();
}
int main()
{
test();
system("pause");
}