设计模式(二)(简单工厂模式、工厂模式、抽象工厂模式)

设计模式

简单工厂模式

不用工厂模式的生成对象的弊端的例子——构造函数最好不要写业务,我们的业务实现太依赖于构造函数了

class Fruit{
public:
    Fryit(string kind){
        if(this->kind=="apple"){}
        else if(this->kind=="banana"){}    
    }

    void getName(){
        if(this->kind=="apple")
            cout<<"I AM APPLE"<<endl;
        else if(this->kind=="banana")
            cout<<"I AM BANANA"<<endl;
    }
};

int main(){

    Fruit apple("apple");
    apple.getName();

    Fruit banana("banana");
    banana.getName();

}

工厂模式的目的就是让业务层和类的构造函数解耦合,尽可能降低一个类的函数复杂度

简单工厂模式怎么做呢?

简单工厂模式例子如下:

class Fruit{
public:
    void getName()=0;
};

class Apple:public Fruit{
public:
    virtual void getName(){
        cout<<"apple"<<endl;
    }
};

class Banana:public Fruit{
public:
    virtual void getName(){
        cout<<"Banana"<<endl;
    }
};

//写一个工厂
class Factory{
public:
    create(string kind){
        if(kind=="apple") return new Apple;
        else if(kind=="banana") return new Banana;
    }

}

int main(){

    Factory *factory=new Factory;

    //要一个苹果
    //抽象的指针指向具体的对象,发生多态
    Fruit *apple=factory->create("apple");
    apple->getName();

    return 0;
}

但是随着水果种类的增加,工厂类中的方法也要进行修改,因此GoF不承认简单工厂模式是设计模式。

工厂模式

简单工厂模式+开闭原则=工厂模式

工厂模式实现代码:

class Fruit{
public:
    void getName()=0;
};

class Apple:public Fruit{
public:
    virtual void getName(){
        cout<<"apple"<<endl;
    }
};

class Banana:public Fruit{
public:
    virtual void getName(){
        cout<<"Banana"<<endl;
    }
};

//抽象工厂
class AbstractFactory{
    public:
        //抽象的生产器
        virtual Fruit* creatFruit()=0;
};

//具体工厂
class APPLEFactory: public AbstractFactory{
public:
    //抽象的生产器
    virtual Fruit*  creatFruit(){
        return new Apple;
    }
};

class BANANAFactory: public AbstractFactory{
public:
    //抽象的生产器
    virtual Fruit*  creatFruit(){
        return new Banana;
    }
};

int main(){

    //来一个生产苹果的工厂
    AbstractFactory *appleFactory = new APPLEFactory;
    Fruit *apple =APPLEFactory->creatFruit();
    apple->getName();

    //来一个香蕉工厂
    //基类指针在子类对象中进行移动是安全的
    //抽象的指针指向具体的对象,符合多态
    AbstractFactory *bananaFactory=new BANANAFactory;
    Fruit *banana=BANANAFactory->creatFruit();
    banana->getName();

    return 0;
}

抽象的工厂模式

目的——尽可能的降低工厂的个数

优点——有工厂模式很方便,增加新产品族很方便

缺点——增加产品结构很麻烦,还有可能需要修改抽象层代码

概念:产品族和产品等级结构

对于普通工厂模式,下图的需求需要对应九种具体工厂类

  • 如果来自同一个产地(厂商),但是他们的每个产品完成的功能接口不同,我们称他们是一个产品族——壹横行
  • 如果一系列产品,他们所提供的接口相同,比如都是苹果,但是来自不同的产地(厂商),我们称他们是一个产品等级结构。——壹纵列

因此,抽象工厂可以按照产品族划分——可以通过中国这个接口获取中国的苹果、中国的香蕉和中国的鸭梨

也可以按照产品等级结构进行划分——但是这样并不能降低工厂类的数量,如果我想要中国的三个厂,就需要分别制造三个类,而上面的方式只知道一个类,这种方式没有做到优化,因此这种方式不合适

实现创建中国和美国产品族,每个产品族中有苹果和香蕉产品等级结构

#include<iostream>
using namespace std;

class Fruit{
public:
	virtual void getName=0;
};

//下面两个类是一个产品族
class ChinaApple:public Fruit{
public:
	virtual void getName(){
		cout<<"chinaApple"<<endl;
	}
};

class ChinaBanana:public Fruit{
public:
    virtual void getName(){
         cout<<"ChinaBanana"<<endl;
    }
};

//下面两个类是一个产品族
class USAApple:public Fruit{
public:
	virtual void getName(){
         cout<<"USAApple"<<endl;
	}
};

class USABanana:public Fruit{
public:
    virtual void getName(){
         cout<<"USABanana"<<endl;
	}
}

//抽象的工厂(根据产品族进行生产)
class AbstractFactory{
public:
	//苹果的生产器
	virtual Fruit*createApple()=0;
	//香蕉的生产器
	virtual Fruit*createBanana()=0;
};

//中国的工厂(虚函数都要实现,哪怕你不用)
class ChinaFactory:public AbstractFactory{
public:
	//苹果的生产器
	virtual Fruit* createApple(){
		return new ChinaApple;
	}

	//香蕉的生产器
	virtual Fruit* createBanana(){
		return new ChinaBanana;
	}
};

//美国的工厂
class USAFactory:public AbstractFactory{
public:
	//苹果的生产器
    virtual Fruit* createApple(){
        return new USAApple;
    }

    //香蕉的生产器
    virtual Fruit* createBanana(){
        return new USABanana;
    }
};


int main(){
	//中国的系列产品
	//利用一个对象生成统一产品族的商品
	AbstractFactory *chinaFactory= new ChinaFactory;
	Fruit *c_apple=chinaFactory->createApple();
	Fruit *c_banana=chinaFactory->createBanana();

	//要一个混合的产品,中国的苹果和美国的香蕉
	//跨产品族的,创建的工厂类就和普通工厂类相同
	AbstractFactory *useFactory= new USAFactory;
	Fruit *u_banana=USAFactory->createBanana();
	
	return 0;
}

总结:

工厂模式的目的——将对象的创建和使用相隔离

例如游戏中,可以通过工厂创建花、创建龙。

  • 简单的工厂模式对于工厂模式来讲,不符合开闭原则,简单工厂模式适用于产品个数极少的情况
  • 工厂模式——工厂数量和产品数量一样多——适用于产品数量相对一般的情况
  • 抽象的工厂模式——目的是在一定的条件下,减少工厂的个数

猜你喜欢

转载自blog.csdn.net/qq_29996285/article/details/88403747