创建型模式
23种模式中可以划分为三大类,分别是 创建型模式,结构型模式,行为模式,这三部分我分三篇来写,本文主要介绍创建型模式
什么事创建型模式?
创建型模式提供了创建对象的机制,能够提升已有代码的灵活性和可复用性。
创建模式分为几种?
- 工厂方法
- 抽象方法
- 生成器
- 原型
- 单例
工厂方法
假如说有个工厂,这个工厂专门生产球类,每次客户都发订单给这个工厂,工厂根据不同订单做好球并发给客户,客户只需知道他需要什么球,不需要知道这其中球是怎么做出来的;这就是工厂模式的通俗的解释,我需要创建一个类,不是直接new,而是由一个工厂对象决定创建出哪一种产品类的实例,简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类,这个产品类怎么new 出来的则不需要调用者关心。
一下是 工厂类demon,根据不同的输入,new出不同的交通工具
namespace Factory_methon {
class ProductBall {
public:
virtual ~ProductBall(){};
virtual void whatBall() = 0;
};
class ProductBasketball : public ProductBall {
public:
void whatBall() { std::cout << "I am Basketball" << std::endl; }
};
class ProductFootball : public ProductBall {
public:
void whatBall() { std::cout << "I am Football" << std::endl; }
};
class Facoty {
public:
ProductBall *createTransport(int i) {
std::cout << "creat!!!" << std::endl;
switch (i) {
case Foot:
return new ProductFootball();
case Basketball:
return new ProductBasketball();
default:
break;
}
}
};
};
优点:
- 你可以避免创建者和具体产品之间的紧密耦合
- 单一职责原则。你可以将产品创建代码放在程序的单一位置,从而使得代码更容易维护。
- 开闭原则。无需更改现有客户端代码,你就可以在程序中引入新的产品类型。
缺点:
- 应用工厂方法模式需要引入许多新的子类,代码可能会因此变得更复杂臃肿。
抽象工厂
它能创建一系列相关的对象,而无需指定其具体类。 抽象工厂可以帮助减少系统的工厂数量的,但前提条件就是这些工厂要具备两个及以上的共性
方法工厂中,根据想要的球类生成球,现在多一个条件,即球有分为不同生产地,原本生产篮球没有指定产地,现在篮球又分为国产和进口的(还有很多个产地),其他的球也如此,这样一来需要添加很多的工厂类,针对这种情况可以进行分类,生成篮球的作为单独一个工厂,这个工厂里又可以生成出来自不同产地的篮球~
namespace Factory_Abstract {
// 不同篮球产地
class AbsProBasketball {
public:
virtual ~AbsProBasketball(){};
virtual std::string whatball() const = 0;
};
class Basketball_USA : public AbsProBasketball {
public:
std::string whatball() const override {
std::cout << "i am Basketball_USA" << std::endl;
}
};
class Basketball_CHINA : public AbsProBasketball {
public:
std::string whatball() const override {
std::cout << "i am Basketball_CHINA" << std::endl;
}
};
// 不同足球产地
class AbsProFootball {
public:
virtual ~AbsProFootball(){};
virtual std::string whatball() const = 0;
};
class Football_USA : public AbsProFootball {
public:
std::string whatball() const override {
std::cout << "i am Football_USA" << std::endl;
}
};
class Football_CHINA : public AbsProFootball {
public:
std::string whatball() const override {
std::cout << "i am Football_CHINA" << std::endl;
}
};
//工厂类 ,有两个纯虚函数需要实现
//分别是生产篮球和足球的
class AbstractFactory {
public:
virtual AbsProFootball *CreateProductFootball() const = 0;
virtual AbsProBasketball *CreateProductBasktball() const = 0;
};
//这里根据不同厂地划分 美国生成的
class ConcreteFactoryBY_USA : public AbstractFactory {
public:
AbsProFootball *CreateProductFootball() const override {
return new Football_USA();
}
AbsProBasketball *CreateProductBasktball() const override {
return new Basketball_USA();
}
};
//中国生产的
class ConcreteFactoryBY_CHINA : public AbstractFactory {
public:
AbsProFootball *CreateProductFootball() const override {
return new Football_CHINA();
}
AbsProBasketball *CreateProductBasktball() const override {
return new Basketball_CHINA();
}
};
}
优点:
- 避免客户端和具体产品代码的耦合。
- 单一职责原则。你可以将产品生成代码抽取到同一位置,使得代码易于维护
- 开闭原则。向应用程序中引入新产品变体时,你无需修改客户端代码。
缺点
- 由于采用该模式需要向应用中引入众多接口和类,代码可能会比之前更加复杂。
生成器
假如你要建一个房子,房子构造本身就很复杂,你需要门,屋顶,窗户,家居等等…这些事是必须的,有些人需要只要一个厕所,有些人又不用,既然这样,那就你来组装,只需要说出你的对房子的基本要求(前提是我有),把这些门,屋顶..都细分开来,供客户选择;创建的顺序都可以由客户定
/ 构建 接口
class Builder {
public:
virtual ~Builder(){};
virtual void ProduceWall() const = 0;
virtual void ProduceDoor() const = 0;
virtual void ProduceWindow() const = 0;
virtual void ProduceRestroom() const = 0;
};
//实现 房子组件的接口
class BUilderHouse : public Builder {
private:
/* data */
public:
House_A *house;
void Rest() { this->house = new House_A(); }
void ProduceWall() const override {
house->part_of_housr_by_order.push_back(" Creat Wall ");
}
void ProduceDoor() const override {
house->part_of_housr_by_order.push_back(" Creat Door ");
}
void ProduceWindow() const override {
house->part_of_housr_by_order.push_back(" Creat Window");
}
void ProduceRestroom() const override {
house->part_of_housr_by_order.push_back(" Creat RestRoom");
}
House_A *getHouse() { return this->house; }
BUilderHouse(/* args */) { this->Rest(); };
~BUilderHouse();
};
//用一个构建类生成房子
// 按照指定的顺序构建
class Builder_by_order {
private:
Builder *builder;
public:
void init_builder(Builder *builder) { this->builder = builder; }
void BuilderHouseA1() {
this->builder->ProduceRestroom();
this->builder->ProduceWall();
this->builder->ProduceWindow();
}
};
void ClienCode(Builder_by_order &Builder) {
BUilderHouse *Houser = new BUilderHouse();
Builder.init_builder(Houser);
Builder.BuilderHouseA1();
House_A *H = Houser->getHouse();
H->ListHouse();
}
};
优点:
- 你可以分步创建对象,暂缓创建步骤或递归运行创建步骤。
- 生成不同形式的产品时,你可以复用相同的制造代码。
- 单一职责原则。你可以将复杂构造代码从产品的业务逻辑中分离出来。
缺点:
- 由于该模式需要新增多个类,因此代码整体复杂程度会有所增加。