设计模式——工厂模式

情景模拟:现在有两家商场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抽象类的。

工厂模式存在以下问题:

  • 工厂类通过接口返回的子类对象是抽象产品类的指针,也就是说父类指针指向了子类对象,这个时候,子类的部分成员是被切掉的,也就是说这个父类指针无法调用子类独有的成员。

  • 当需要增加子类的数量的时候,需要在工厂类中更改代码,那么工厂类的接口就永远不可能封闭,这不符合开放封闭原则。

  • 工厂模式只适合为一种类创建提供接口。