设计模式——工厂模式
情景模拟:现在有两家商场A和B,他们都需要采购不同类型的服装,A商场采取的做法是,从专门生产某一类型服装的厂家采购那一类型的服装,那么A商场就需要从不同的厂家采购服装;B商场采取的做法是,将采购清单给一个生产各种类型的厂家,厂家直接根据清单生产B商场所需要的服装。
当若干子类继承于一个抽象类,通常我们实例化某个子类的方法是直接实例化哪个具体的子类,当子类过多,并且子类类名相似时,很容易给自己带来困扰。工厂模式是将子类的实例化封装在基类中,通过传入不同的参数,实例化具体的子类,并返回该子类的对象指针。
源码实例:
// factory.hpp
#pragma once
#include <iostream>
#include "product.hpp"
using namespace std;
enum Ptype{
PA,
PB
};
class Factory
{
public:
Factory();
Factory(Factory &&) = default;
Factory(const Factory &) = default;
Factory &operator=(Factory &&) = default;
Factory &operator=(const Factory &) = default;
~Factory();
Product *createProduct(Ptype pt);
protected:
private:
};
// factory.cpp
#include "factory.hpp"
Factory::Factory()
{
}
Factory::~Factory()
{
}
Product* Factory::createProduct(Ptype pt){
Product *p = nullptr;
switch(pt){
case PA:
p = new ProductA();
break;
case PB:
p = new ProductB();
break;
default:
break;
}
return p;
}
// product.hpp
#include <iostream>
using namespace std;
class Product
{
public:
Product();
Product(Product &&) = default;
Product(const Product &) = default;
Product &operator=(Product &&) = default;
Product &operator=(const Product &) = default;
virtual ~Product() = 0;
void productBase();
virtual void productSurface();
virtual void productF();
private:
};
class ProductA : public Product
{
public:
ProductA();
ProductA(ProductA &&) = default;
ProductA(const ProductA &) = default;
ProductA &operator=(ProductA &&) = default;
ProductA &operator=(const ProductA &) = default;
~ProductA();
void productF();
void productSurface();
private:
};
class ProductB : public Product
{
public:
ProductB();
ProductB(ProductB &&) = default;
ProductB(const ProductB &) = default;
ProductB &operator=(ProductB &&) = default;
ProductB &operator=(const ProductB &) = default;
~ProductB();
void productF();
void productSurface();
private:
};
// product.cpp
#include "product.hpp"
Product::Product()
{
}
Product::~Product()
{
}
void Product::productBase()
{
cout << "first product basic core" << endl;
}
void Product::productSurface()
{
cout << "product default surface" << endl;
}
void Product::productF()
{
productBase();
productSurface();
}
ProductA::ProductA()
{
}
ProductA::~ProductA()
{
}
void ProductA::productF()
{
productBase();
productSurface();
}
void ProductA::productSurface()
{
cout << "product A surface" << endl;
}
ProductB::ProductB()
{
}
ProductB::~ProductB()
{
}
void ProductB::productF()
{
productBase();
productSurface();
}
void ProductB::productSurface()
{
cout << "product B surface" << endl;
}
// main.cpp
#include <iostream>
#include "factory.hpp"
#include <memory>
using namespace std;
int main()
{
shared_ptr<Factory> pF(new Factory());
shared_ptr<Product> pa(pF->createProduct(Ptype::PA));
shared_ptr<Product> pb(pF->createProduct(Ptype::PB));
pa->productF();
pb->productF();
return 0;
}
Factory类提供一个对象初始化的接口,通过传入不同的参数,初始化不同的子类的对象,这些子类都是继承于Product抽象类的。
工厂模式存在以下问题:
-
工厂类通过接口返回的子类对象是抽象产品类的指针,也就是说父类指针指向了子类对象,这个时候,子类的部分成员是被切掉的,也就是说这个父类指针无法调用子类独有的成员。
-
当需要增加子类的数量的时候,需要在工厂类中更改代码,那么工厂类的接口就永远不可能封闭,这不符合开放封闭原则。
-
工厂模式只适合为一种类创建提供接口。