【设计模式】创建者模式_工厂、抽象工厂、建造者

设计模式六大原则

  • 开闭原则(Open Close Principle)

开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,而是要扩展原有代码。

  1. 单一职责原则

不要存在多于一个导致类变更的原因,也就是说每个类应该实现单一的职责,如若不然,就应该把类拆分。

  1. 里氏替换原则

里氏代换原则(Liskov Substitution Principle LSP)中说,任何基类可以出现的地方,一定可以用其子类替换。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。

  1. 依赖倒换原则

面向接口编程,依赖于抽象而不依赖于具体。写代码时用到具体类时,不与具体类交互,而与具体类的上层接口交互。

  1. 接口隔离原则

每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。使用多个隔离的接口,比使用单个接口(多个接口方法集合到一个的接口)要好。

  1. 迪米特法则(最少知道原则)

一个类对自己依赖的类知道的越少越好。也就是说无论被依赖的类多么复杂,都应该将逻辑封装在方法的内部,通过public方法提供给外部。这样当被依赖的类变化时,才能最小的影响该类。

  1. 合成复用原则

尽量首先使用合成/聚合的方式,而不是使用继承。

创建型模式

  1. 工厂模式

简单工厂 工厂方法模式 抽象工厂模式

有一家物流公司,可以提供不同类型的运输工具,进行物流运输。客户要走陆运,就从公司里要一辆卡车,要海运就从公司要一艘船

enum VTYPE {SHIP, TRUCK};     
class Vehicles
{    
public:    
    virtual void Show() = 0;  
};    
//陆运    
class Truck: public Vehicles    
{    
public:    
    void Show() { cout<<"This is a truck"<<endl; }    
};    
//海运    
class Ship: public Vehicles    
{    
public:    
    void Show() { cout<<"This is a ship"<<endl; }    
};    
//唯一的工厂,可以生产不同的载具,在内部判断    
class Factory    
{    
public:     
    Vehicles* CreateVehicles(enum VTYPE Vtype)    
    {    
        if(Vtype == SHIP) //工厂内部判断    
            return new Ship(); //生产船
        else if(Vtype == TRUCK)    
            return new Truck(); //生产卡车
        else    
            return nullptr;    
    }    
};   
  • 要增加一个新的载具类型,需要修改工厂类,违背开闭原则

所以出现了工厂方法,不再通过修改工厂实现,而实创建新的工厂

  • 模式定义
  • 定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂模式使得一个类的实例化延迟到子类完成。
#include <iostream>
using namespace std;

class Vehicles
{
public:
    virtual void Show() = 0;
};
//陆运    
class Truck : public Vehicles
{
public:
    void Show() { cout << "This is a truck" << endl; }
};
//海运    
class Ship : public Vehicles
{
public:
    void Show() { cout << "This is a ship" << endl; }
};
class Factory
{
public:
    virtual Vehicles* CreateVehicle() = 0;
};
//生产船的工厂    
class FactoryShip : public Factory
{
public:
    Ship* CreateVehicle() { return new Ship(); }
};
//生产卡车的工厂    
class FactoryTruck : public Factory
{
public:
    Truck* CreateVehicle() { return new Truck(); }
};

int main()
{
    FactoryTruck *m_TruckFactory = new FactoryTruck();
    FactoryShip *m_ShipFactory = new FactoryShip();

    Vehicles* m_Truck = m_TruckFactory->CreateVehicle();
    m_Truck->Show();

    Vehicles* m_Ship = m_ShipFactory->CreateVehicle();
    m_Ship->Show();

    return 0;

}
  • 问题在于 每增加一种产品,就会增加一个工厂类

现在公司业务升级,提供了更大载荷的承运方案,需要生产不同规格的卡车、轮船

#include <iostream>
using namespace std;

class Vehicles
{
public:
    virtual void Show() = 0;
};
//陆运    
class Truck : public Vehicles
{
public:
    void Show() { cout << "This is a truck" << endl; }
};
//海运    
class Ship : public Vehicles
{
public:
    void Show() { cout << "This is a ship" << endl; }
};
//大型载具    
class BigVehicles
{
public:
    virtual void Show() = 0;
};
class BigTruck : public BigVehicles
{
public:
    void Show() { cout << "This is a BIG truck" << endl; }

};
class BigShip : public BigVehicles
{
public:
    void Show() { cout << "This is a BIG ship" << endl; }
};
//工厂    
class Factory
{
public:
    virtual Vehicles* CreateVehicles() = 0;
    virtual BigVehicles* CreateBigVehicles() = 0;
};
//卡车工厂,生产大型、小型卡车
class FactoryTruck :public Factory
{
public:
    Vehicles* CreateVehicles() { return new Truck(); }
    BigVehicles* CreateBigVehicles() { return new BigTruck(); }
};
//船工厂,生产大型、小型船
class FactoryShip : public Factory
{
public:
    Vehicles* CreateVehicles() { return new Ship(); }
    BigVehicles* CreateBigVehicles() { return new BigShip(); }
};

int main()
{
    FactoryTruck* m_TruckFactory = new FactoryTruck();
    FactoryShip* m_ShipFactory = new FactoryShip();

    Vehicles* m_Truck = m_TruckFactory->CreateVehicles();
    Vehicles* m_Ship = m_ShipFactory->CreateVehicles();

    BigVehicles* m_BigTruck = m_TruckFactory->CreateBigVehicles();
    BigVehicles* m_BigShip = m_ShipFactory->CreateBigVehicles();

    m_Ship->Show();
    m_Truck->Show();
    m_BigShip->Show();
    m_BigTruck->Show();

    return 0;
}
  • 如果需要拓展抽象工厂里面的方法会比较麻烦,因为我们必须修改抽象类以及添加对应的产品,这样修改量比较大,但是每种产品之间相互解耦。

  1. 建造者模式
  • 模式意图
    将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

特点: 用于对复杂对象的构造、初始化,与工厂模式不同的是,建造者的目的在于把复杂构造过程从不同对象展现中抽离出来,使得同样的构造工序可以展现出不同的产品对象。

  • 适用场景

  • 相同的方法,不同的执行顺序,产生不同的结果时,可以采用建造者模式。

  • 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,则可以使用该模式。

  • 产品类非常复杂,或者产品类中的方法调用顺序不同产生了不同的效能,这个时候使用建造者模式。

都builder了,就举一个盖房子的例子
比如盖一栋房子需要 地基 墙体 房顶三部分组成

我们创建建筑物类Building
抽象出建造方法类Builder
创建一个HouseBuilder用来描述具体各部件的构造方式
最后用Director类对构造流程进行管理,通过它选择不同的构造方式,并明确具体的构造流程,最终得到我们的复杂产品

#include <iostream>
#include <vector>
using namespace std;

class Building
{
private:
	vector<string> BuildingComponents;
public:
	void SetBasement(string basement) {
		BuildingComponents.push_back(basement);
	}
	void SetWall(string wall) {
		BuildingComponents.push_back(wall);
	}
	void SetRoof(string roof) {
		BuildingComponents.push_back(roof);
	}

	void PrintBuilding() {
		for (int i = BuildingComponents.size() - 1; i >= 0; i--) {
			cout << BuildingComponents[i] << endl;
		}
		return;
	}
};

class Builder
{
public:
	virtual void BuildBasement() = 0;
	virtual void BuildWall() = 0;
	virtual void BuildRoof() = 0;
	virtual void GetBuilding() = 0;
};

class HouseBuilder : public Builder
{
private:
	Building house;

public:
	void BuildBasement() {
		house.SetBasement("这里是house地基");
	}
	void BuildWall() {
		house.SetWall("这里是house墙壁");
	}
	void BuildRoof() {
		house.SetRoof("  house房顶!  ");
	}
	void GetBuilding() {
		house.PrintBuilding();
	}
};

class Director
{
private:
	Builder* m_pBuilder;
public:
	Director(Builder* builder) { m_pBuilder = builder; }
	void Create() {
		m_pBuilder->BuildBasement();
		m_pBuilder->BuildWall();
		m_pBuilder->BuildWall();
		m_pBuilder->BuildWall();
		m_pBuilder->BuildWall();
		m_pBuilder->BuildRoof();
		m_pBuilder->GetBuilding();
	}
};

int main()
{
	HouseBuilder ahouse;
	Director director(&ahouse);
	director.Create();
	return 0;
}
  1. 原型模式
  • 模式意图
    用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象

特点:

  • 性能较好,原型模式是内存二进制流的复制,会比直接new一个对象性能较好
  • 因为是直接复制,所以绕开了构造函数,这是优点也是缺点,要看实际使用场景
#include <iostream>
using namespace std;
//具体的实现类
class Sheep
{
public:
    Sheep(int id, string name) :m_id(id), m_name(name)
    {

        cout << "new Sheep Comes" << endl;
    }

    //关键代码拷贝构造函数
    Sheep(const Sheep& obj)
    {
        this->m_id = obj.m_id;
        this->m_name = obj.m_name;
    }
    //关键代码克隆函数,返回return new Sheep(*this)
    Sheep* clone()
    {
        return new Sheep(*this);
    }
    void show()
    {
        cout << "id  :" << m_id << endl;
        cout << "name:" << m_name.data() << endl;
        cout << "Sheep id address:" << &m_id << endl;
        cout << "Sheep name address:" << &m_name << endl;
    }
private:
    int m_id;
    string m_name;
};
int main()
{
    Sheep* s1 = new Sheep(9, "肖恩");
    s1->show();
    Sheep* s2 = s1->clone();
    s2->show();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值