前言
创建型为了创建东西才是有用的,创建型设计模式使用的场景:
1、创建一个东西;
2、可重复利用;
3、灵活性高,代码可因地制宜。
Factory Method(工厂模式)
工厂模式将目的将创建对象的具体过程屏蔽隔离起来,从而达到更高的灵活性,工厂模式可以分为三类:
- 简单工厂模式(Simple Factory)
- 工厂方法模式(Factory Method)
- 抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。《设计模式》一书中将工厂模式分为两类:工厂方法模式与抽象工厂模式。将简单工厂模式看为工厂方法模式的一种特例,两者归为一类。
Simple Factory(简单工厂)
主要用于创建对象。新添加类时,不会影响以前的系统代码。核心思想是用一个工厂来根据输入的条件产生不同的类,然后根据不同类的 virtual 函数得到不同的结果。
GOOD:适用于不同情况创建不同的类时
BUG:客户端必须要知道基类和工厂类,耦合性差
simpleFactory.h
#ifndef CLION_TEST_SIMPLEFACTORY_H
#define CLION_TEST_SIMPLEFACTORY_H//基类
class COperation {
public:int m_nFirst;int m_nSecond;virtual double GetResult() {double dResult = 0;return dResult;}
};//加法
class AddOperation : public COperation {
public:double GetResult() final {return m_nFirst + m_nSecond;}
};//减法
class SubOperation : public COperation {
public:double GetResult() final {return m_nFirst - m_nSecond;}
};//工厂类
class CCalculatorFactory {
public:static COperation *Create(char cOperator) {COperation *oper;switch (cOperator) {case '+':oper = new AddOperation();break;case '-':oper = new SubOperation();break;default:oper = new AddOperation();break;}return oper;}
};#endif //CLION_TEST_SIMPLEFACTORY_H
main.cpp
#include <iostream>
#include "simpleFactory.h"using namespace std;int main() {int a = 1;int b = 2;COperation * op=CCalculatorFactory::Create('-');op->m_nFirst=a;op->m_nSecond=b;cout<<op->GetResult()<<endl;return 0;
}
Factory Method(工厂方法)
GOOD:修正了简单工厂模式中不遵守开放-封闭原则。工厂方法模式把选择判断移到了客户端去实现,如果想添加新功能就不用修改原来的类,直接修改客户端即可。
一个产品对应一个工厂类。
factorymethod.h
#ifndef CLION_TEST_FACTORYMETHOD_H
#define CLION_TEST_FACTORYMETHOD_H#include <iostream>
#include <string>using namespace std;// 实例基类,相当于Product
class LeiFeng {
public:virtual void Sweep() {cout << "雷锋扫地" << endl;}
};// 学雷锋的大学生,相当于ConcreteProduct
class Student : public LeiFeng {
public:void Sweep() final {cout << "大学生扫地" << endl;}
};// 学雷锋的志愿者,相当于ConcreteProduct
class Volenter : public LeiFeng {
public:void Sweep() final {cout << "志愿者" << endl;}
};// 工厂基类 Creator
class LeiFengFactory {
public:virtual LeiFeng *CreateLeiFeng() {return new LeiFeng();}
};// 工厂具体类
class StudentFactory : public LeiFengFactory {
public:LeiFeng *CreateLeiFeng() final {return new Student();}
};class VolenterFactory : public LeiFengFactory {
public:LeiFeng* CreateLeiFeng() final {return new Volenter();}
};#endif //CLION_TEST_FACTORYMETHOD_H
main.cpp
#include "factorymethod.h"using namespace std;int main() {// 工厂方法LeiFengFactory *sf = new StudentFactory();LeiFeng *s = sf->CreateLeiFeng();s->Sweep();delete sf;delete s;sf = nullptr;s = nullptr;return 0;
}
Abstract Factory(抽象工厂)
GOOD:定义了一个创建一系列相关或相互依赖的接口,而无需指定它们的具体类。
用于交换产品系列,如 ACCESS>SQL SERVER;
产品的具体类名被具体工厂的实现分离
abstractfactory.h
#ifndef CLION_TEST_ABSTRACTFACTORY_H
#define CLION_TEST_ABSTRACTFACTORY_H#include <iostream>using namespace std;// 用户抽象接口
class IUser {
public:virtual void GetUser() = 0;virtual void InsertUser() = 0;
};// 部门抽象接口
class IDepartment {
public:virtual void GetDepartment() = 0;virtual void InsertDepartment() = 0;
};// ACCESS用户
class CAccessUser : public IUser {
public:void GetUser() final {cout << "Access GetUser" << endl;}void InsertUser() final {cout << "Access InsertUser" << endl;}
};// ACCESS部门
class CAccessDepartment : public IDepartment {
public:void GetDepartment() final {cout << "Access GetDepartment" << endl;}void InsertDepartment() final {cout << "Access InsertDepartment" << endl;}
};// SQL用户
class CSqlUser : public IUser {
public:void GetUser() final {cout << "Sql User" << endl;}void InsertUser() final {cout << "Sql User" << endl;}
};// SQL部门类
class CSqlDepartment : public IDepartment {
public:void GetDepartment() final {cout << "sql getDepartment" << endl;}void InsertDepartment() final {cout << "sql insertdepartment" << endl;}
};// 抽象工厂
class IFactory {
public:virtual IUser *CreateUser() = 0;virtual IDepartment *CreateDepartment() = 0;
};// ACCESS工厂
class AccessFactory : public IFactory {
public:IUser *CreateUser() final {return new CAccessUser();}IDepartment *CreateDepartment() final {return new CAccessDepartment();}
};// SQL工厂
class SqlFactory : public IFactory {
public:IUser *CreateUser() final {return new CSqlUser();}IDepartment *CreateDepartment() final {return new CSqlDepartment();}
};#endif //CLION_TEST_ABSTRACTFACTORY_H
main.cpp
#include "abstractfactory.h"using namespace std;int main() {system("chcp 65001");// 抽象工厂模式///cout<<"SQL用户"<<endl;IFactory* factory = new SqlFactory();IUser* user = factory->CreateUser();IDepartment* department = factory->CreateDepartment();user->GetUser();department->GetDepartment();///cout<<"ACCESS用户"<<endl;factory = new AccessFactory();user = factory->CreateUser();department = factory->CreateDepartment();user->GetUser();department->GetDepartment();return 0;
}
Builder(建造者)
GOOD:在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时适用。
builder.h
#ifndef CLION_TEST_BUILDER_H
#define CLION_TEST_BUILDER_H#include <string>
#include <iostream>
#include <vector>using namespace std;// 最终的产品类
class Product {
private:vector<string> m_product;
public:void Add(string strtemp) {m_product.push_back(strtemp);}void Show() {for (auto p = m_product.begin(); p != m_product.end(); ++p) {cout << *p << endl;}}
};// 建设者基类
class Builder {
public:virtual void BuilderA() = 0;virtual void BuilderB() = 0;virtual Product *GetResult() = 0;
};// 第一种建造方式
class ConcreteBuilder1 : public Builder {
private:Product *m_proudct;
public:ConcreteBuilder1() {m_proudct = new Product();}void BuilderA() final {m_proudct->Add("one");}void BuilderB() final {m_proudct->Add("two");}Product *GetResult() final {return m_proudct;}
};// 第二种建造方式
class ConcreteBuilder2 : public Builder {
private:Product *m_proudct;
public:ConcreteBuilder2() {m_proudct = new Product();}void BuilderA() final {m_proudct->Add("A");}void BuilderB() final {m_proudct->Add("B");}Product *GetResult() final {return m_proudct;}
};// 指挥者类
class Direct {
public:void Construct(Builder *temp) {temp->BuilderA();temp->BuilderB();}
};#endif //CLION_TEST_BUILDER_H
main.cpp
#include "builder.h"
using namespace std;int main() {system("chcp 65001");// 建造者模式Direct *p = new Direct();Builder* b1 = new ConcreteBuilder1();Builder* b2 = new ConcreteBuilder2();p->Construct(b1); // 调用第一种方式Product* pb1 = b1->GetResult();pb1->Show();p->Construct(b2); // 调用第二种方式Product* pb2 = b2->GetResult();pb2->Show();return 0;
}
Prototype(原型)
GOOD:从一个对象再创建另外一个可定制的对象,而无需知道任何创建的细节。并能提高创建的性能。 说白了就 COPY 技术,把一个对象完整的 COPY 出一份。
注:此处书写的是浅拷贝,当需要复制的内容更改时不影响原先的内容,需要进行深拷贝,好奇地是原型模式直接使用拷贝赋值或拷贝构造函数不就可以了嘛。
prototype.h
#ifndef CLION_TEST_PROTOTYPE_H
#define CLION_TEST_PROTOTYPE_H#include <iostream>
#include <vector>
#include <string>using namespace std;// 抽象基类
class Prototype {
private:string m_strName;
public:Prototype(string strName) { m_strName = strName; }Prototype() { m_strName = ""; }void Show() {cout << m_strName << endl;}virtual Prototype *Clone() = 0;
};// class ConcretePrototype1
class ConcretePrototype1 : public Prototype {
public:ConcretePrototype1(string strName) : Prototype(strName) {}ConcretePrototype1() {}Prototype *Clone() final {ConcretePrototype1 *p = new ConcretePrototype1();*p = *this; // 复制对象return p;}
};// class ConcretePrototype2
class ConcretePrototype2 : public Prototype {
public:ConcretePrototype2(string strName) : Prototype(strName) {}ConcretePrototype2() {}Prototype *Clone() final {ConcretePrototype2 *p = new ConcretePrototype2();*p = *this; // 复制对象return p;}
};#endif //CLION_TEST_PROTOTYPE_H
main.cpp
#include <iostream>
#include "prototype.h"using namespace std;int main() {system("chcp 65001");// 客户端ConcretePrototype1* test1 = new ConcretePrototype1("小王");ConcretePrototype2* test2 = (ConcretePrototype2*)test1->Clone();test1->Show();test2->Show();return 0;
}