(四)Head first design patterns工厂篇(c++)

工厂篇

参考:https://zhuanlan.zhihu.com/p/476420041

什么是工厂?负责创建对象,实现其细节的类被称为工厂(Factory)。

简单工厂模式

简单工厂是对工厂最基础的实现方式,其实都不能算作是一种设计模式,而是更像是一种编程习惯。

简单工厂的目的是将“类实例化的操作”与“使用对象的操作”分开,让使用者不用知道具体参数就可以实例化出所需要的“产品”类,从而避免了在客户端代码中显式指定,实现了解耦。 即使用者可直接消费产品而不需要知道其生产的细节。

简单工厂实现的逻辑是创建一个factory类,在类成员函数中通过判断传进来的参数用new方法生成不同的product,将product返回。

(四)Head first design patterns工厂篇(c++)_第1张图片

代码示例

#include 
#include "Product.cpp"

using namespace std;

class SimpleFactory{
public:
    Product* getProduct(PRODUCT_TYPE type){
        Product* product = nullptr;
        switch(type){
            case APPLE:
                product = new AppleProduct(5);
                break;
            case BANANA:
                product = new BananaProduct(2);
                break;
            case PEAR:
                product = new PearProduct(3);
                break;
            default:
                cout << "No this product." << std::endl;
        }
        return product;
    }
};

int main(){
    SimpleFactory *factory = new SimpleFactory();
    Product* apple  = factory->getProduct(APPLE);
    Product* banana = factory->getProduct(BANANA);
    Product* pear   = factory->getProduct(PEAR);
    delete apple;
    delete banana;
    delete pear;
}

这种方法的缺点很明显,当product的种类变多时,需要不断地进入SimpleFactory里修改里面的分支语句。这种做法违背了开闭原则(对扩展开放,对修改关闭)。并且此工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受到影响。

静态工厂模式

静态工厂类似于简单工厂,区别就是里面的创建方法采用了设为成了static。这样做的好处可以不需要实例化此类便可调用该静态方法。并且静态方法可以访问类中的私有成员,这样这个类的构造函数是private属性时,外界没法直接调用构造函数创建此对象,但是可以通过此静态方法创建此对象。这样做对创建对象进行了更严格的控制。

#include
#include

using namespace std;

template
class Lists{
public:
    Lists(){} //私有构造函数,防止通过构造函数直接创建对象
public:
    static Lists* newList(){
        return new Lists;
    }
    vector v;
};

int main(){
    // Lists l1; //error
    Lists* l1 = Lists::newList();
     l1->v.push_back(100.99);
    std::cout << l1->v[0] << std::endl; 
}

工厂模式

工厂模式其实就是把SimpleFactory里的分支语句每一条拎出来单独封装成工厂的子类。这样原先由工厂负责判断生产的逻辑转移成由子类决定如何生产。这样保证了开闭原则——当有新的产品加入时不需要去修改factory类,而只是增加生产此产品的工厂类。​​​​​​​(四)Head first design patterns工厂篇(c++)_第2张图片

需要创建什么样的产品则实例化相应的子工厂。

示例代码

#include 
#include "Product.cpp"

using namespace std;

class Factory{
public:
    virtual Product* getProduct()=0;
};
class AppleFactory : public Factory{
    Product* getProduct(){
        Product* product = new AppleProduct(5);
        return product;
    }
};
class BananaFactory : public Factory{
    Product* getProduct(){
        Product* product = new BananaProduct(2);
        return product;
    }
};
class PearFactory : public Factory{
    Product* getProduct(){
        Product* product = new PearProduct(3);
        return product;
    }
};

int main(){
    Factory* fApple  = new AppleFactory();
    Factory* fBanana = new BananaFactory();
    Factory* fPear   = new PearFactory();
    Product* apple = fApple->getProduct();
    Product* banana = fBanana->getProduct();
    Product* pear = fPear->getProduct();
    delete apple;
    delete banana;
    delete pear;
    delete fApple;
    delete fBanana;
    delete fPear;
}

抽象工厂模式

抽象工厂模式跟工厂模式很类似,可以说是同一套逻辑。唯一的变化是工厂模式针对的是一种产品,而抽象工厂处理的是一族产品。

比方说,之前你的任务是得到一种水果,当你需要苹果这个产品的时候,你去找苹果厂;当你需要梨时,你去找梨厂。而现在你接到的任务是你需要做一个水果拼盘,水果拼盘的组成是苹果、香蕉和梨。你可以决定是找佳沃生产或者找百果园生产。这个时候工厂的生产目的是一族产品而不是单一的产品了。于是可以写一个抽象的Factory类,再具体实现一个佳沃Factory类和一个百果园Factory。每个子Factory都会可以生产apple,banana和pear三种水果。如果你想要佳沃生产的水果拼盘,可以找JFactory,如果想要百果园生产的水果拼盘,则找PFactory。

(四)Head first design patterns工厂篇(c++)_第3张图片

代码实例

#include 

using namespace std;

enum PRODUCT_TYPE{APPLE, BANANA, PEAR};

class Product{
public:
    Product(){}
    virtual ~Product(){};
};

class AppleProduct : public Product{};
class JApple : public AppleProduct{
public:
    JApple(){
        std::cout << "get an apple from JOYVIO." << std::endl;
    }
    virtual ~JApple(){
        std::cout << "eat an apple from JOYVIO." << std::endl;
    } 
};
class PApple : public AppleProduct{
public:
    PApple(){
        std::cout << "get an apple from Pagoda." << std::endl;
    }
    virtual ~PApple(){
        std::cout << "eat an apple from Pagoda." << std::endl;
    } 
};
class BananaProduct : public Product{};
class JBanana : public BananaProduct{
public:
    JBanana(){
        std::cout << "get an banana from JOYVIO." << std::endl;
    }
    virtual ~JBanana(){
        std::cout << "eat an banana from JOYVIO." << std::endl;
    } 
};
class PBanana : public BananaProduct{
public:
    PBanana(){
        std::cout << "get an banana from Pagoda." << std::endl;
    }
    virtual ~PBanana(){
        std::cout << "eat an banana from Pagoda." << std::endl;
    } 
};
class PearProduct : public Product{};
class JPear : public PearProduct{
public:
    JPear(){
        std::cout << "get an pear form JOYVIO." << std::endl;
    }
    virtual ~JPear(){
        std::cout << "eat an pear from JOYVIO." << std::endl;
    } 
};
class PPear : public PearProduct{
public:
    PPear(){
        std::cout << "get an pear from Pagoda." << std::endl;
    }
    virtual ~PPear(){
        std::cout << "eat an pear from Pagoda." << std::endl;
    } 
};

class Factory{
public:
    virtual Product* getApple()=0;
    virtual Product* getBanana()=0;
    virtual Product* getPear()=0;
};
class JFactory : public Factory{
public:
    Product* getApple(){
        return new JApple;
    }
    Product* getBanana(){
        return new JBanana;
    }
    Product* getPear(){
        return new JPear;
    }
};
class PFactory : public Factory{
public:
    Product* getApple(){
        return new PApple;
    }
    Product* getBanana(){
        return new PBanana;
    }
    Product* getPear(){
        return new PPear;
    }
};


int main(){
    PFactory* factory = new PFactory;
    Product* a = factory->getApple();
    Product* b = factory->getBanana();
    Product* p = factory->getPear();
    delete factory;
    delete a;
    delete b;
    delete p;
}

当你用工厂模式,如果你需要添加一种水果,比如你要的是菠萝。这个时候你创建了菠萝这个类,所需要的是再创建一个生产菠萝的子类继承基类Factory。工厂模式可以做到在你添加产品或者删除产品的时候,无须对原有类进行修改,遵守了开闭原则。

抽象工厂模式是在添加一族产品的时候无须对原有类进行修改。设想你现在不满足于佳沃和百果园的水果,你想从小蔡家进水果,这个时候在创建了小蔡家相应的产品后,只需要再创建一个专门用来生产小蔡家水果的factory。同样做到了开闭原则。但是如果需要添加产品种类,还是得对原有类进行修改。比如说你的水果拼盘不再是苹果、香蕉和梨三种搭配,而是需要菠萝,草莓...

你可能感兴趣的:(设计模式cpp,设计模式)