主要关注点是:“怎样创建对象?”
主要特点是:“将对象的创建与使用分离”
这样使用者不需要关注对象的创建细节,对象的创建由相应的工厂实现。
(隐藏了对象如何被创建和组合在一起)
包括五种:
简单工厂模式(Simple Factory)
工厂方法模式(Factory Method)
抽象工厂模式(Abstract Factory)
建造者模式(Builder)
单例模式(Singleton)
简单工厂模式(Simple Factory Pattern)因为内部使用静态方法根据不同参数构造不同产品对象实例,也称静态工厂方法模式。
在简单工厂模式中,可以根据参数的不同返回不同实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
简单工厂模式的核心是,对于一个父类的多个继承子类,工厂对象的工厂函数根据用户输入,自动new出一个子类对象并返回其父类的指针,这样利用父类的指针执行父类的虚函数,就可以动态绑定子类的重写函数,从而实现多态。
#include
#include
#include
#include
using namespace std;
//抽象产品类-操作
class Operation
{
private:
double A, B;
public:
Operation() :A(0), B(0) {}
double GetA() const { return A; }
double GetB() const { return B; }
void SetA(double x) { A = x; }
void SetB(double y) { B = y; }
virtual double GetResult() = 0;
/*
double GetA() const{return A;}中的const:
只有函数是一个类的非静态成员函数才可以。
类的非静态成员函数不管有几个参数,都会隐形的传入一个参数this
this是指向该类的指针,加了const以后,表示不可以更改这个对象的成员变量。
如return A++; 编译的时候就会报错。其实是A是this->A
*/
};
//具体产品类-加法
class Add :public Operation
{
public:
double GetResult() { return GetA() + GetB(); }
};
//具体产品类-减法
class Sub :public Operation
{
public:
double GetResult() { return GetA() - GetB(); }
};
//具体产品类-乘法
class Mul :public Operation
{
public:
double GetResult() { return GetA()*GetB(); }
};
//具体产品类-除法
class Div :public Operation
{
public:
double GetResult() { return GetA() / GetB(); }
};
//工厂类
class SimpleFactory
{
public:
static Operation* CreateOperator(char ch)
{
Operation* p=NULL;
switch (ch)
{
case '+':
p = new Add();
break;
case '-':
p = new Sub();
break;
case '*':
p = new Mul();
break;
case '/':
p = new Div();
break;
}
return p;
}
};
int main()
{
double A = 0;
double B = 0;
char ch= '\0';
cin >> A >> ch >> B;
Operation* op=SimpleFactory::CreateOperator(ch);
op->SetA(A);
op->SetB(B);
cout << op->GetResult() << endl;
delete op;
return 0;
}
现在对系统进行修改,不再设计一个按钮工厂类来统一负责所有产品的创建,而是将具体按钮的创建过程交给专门的工厂子类去完成。
在工厂方法模式中,工厂父类定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象。
这样子做的目的时将产品类的实例操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。
#include
using namespace std;
//抽象产品
class Product
{
public:
virtual void show() = 0;
};
//具体产品1
class ConcreteProduct1 :public Product
{
public:
void show()
{
cout << "具体产品1" << endl;
}
};
//具体产品2
class ConcreteProduct2 :public Product
{
public:
void show()
{
cout << "具体产品2" << endl;
}
};
//抽象工厂
class AbstractFactory
{
public:
virtual Product* newProduct() = 0;
};
//具体工厂1
class ConcreteFactory1 :public AbstractFactory
{
public:
Product* newProduct()
{
return new ConcreteProduct1();
}
};
//具体工厂2
class ConcreteFactory2 :public AbstractFactory
{
public:
Product* newProduct()
{
return new ConcreteProduct2();
}
};
int main()
{
ConcreteFactory1 cf_1;
Product *pd_1 = cf_1.newProduct();
pd_1->show();
ConcreteFactory2 cf_2;
Product *pd_2 = cf_2.newProduct();
pd_2->show();
delete pd_1,pd_2;
return 0;
}
#include
#include
using namespace std;
//抽象产品
class Log
{
private :
string name;
public:
string getName() { return name; }
void setName(string name) { this->name = name; }
virtual void writeLog() = 0;
};
//具体产品
class FileLog :public Log
{
public:
void writeLog()
{
cout << this->getName() << endl;
}
};
class DatabaseLog :public Log
{
public:
void writeLog()
{
cout << this->getName() << endl;
}
};
//抽象工厂
class LogFactory
{
public:
virtual Log* createLog(string log)throw(int, string);
};
//具体工厂
class FileLogFactory :public LogFactory
{
public:
Log* createLog(string log)throw(int) {
return new FileLog();
}
};
//具体工厂
class DatabaseFactory :public LogFactory
{
public:
Log* createLog(string log)throw(string)
{
return new DatabaseLog();
}
};
Log * LogFactory::createLog(string log) throw(int, string)
{
return nullptr;
}
class Client
{
public:
static void main()throw (int, string) {
LogFactory* a = new FileLogFactory();
Log* b = a->createLog("filelog");
b->setName("filelog");
b->writeLog();
delete a, b;
}
};
int main(){
Client c;
c.main();
return 0;
}
使用面向对象的多态性
这个核心的工厂类不再负责所有产品的创建,而是将具体的创建工作去做。这个核心类只负责给出具体工厂必须实现的接口。
这是得工作方法模式可以允许系统在不修改工厂角色的情况下引进新产品。
在工厂模式中具体工厂负责生产具体的产品,每一个具体工厂对应一个具体产品,一个具体工厂只有一个工厂方法或者一组重载的工厂方法。但是有时候我们需要一个工厂提供多个产品对象,而不是单一的产品对象。
当系统所提供的工厂所需生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构中属于不同类型的具体产品时需要使用抽象工厂模式。
工厂模式针对是一个产品等级结构,抽象工厂模式则需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建。当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、有效率。
抽象工厂模式:提供一个创建一系列相关或者相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式又称为Kit模式。
#include
#include
using namespace std;
//抽象产品-产品等级A
class AbstractProductA {
public:
virtual void use() = 0;
};
//具体产品-产品等级A-产品族1
class ProductA1:public AbstractProductA
{
public:
void use() {
cout << "use Product A1"<<endl;
}
};
//具体产品-产品等级A-产品族2
class ProductA2:public AbstractProductA
{
public:
void use() {
cout << "use Product A2" << endl;
}
};
//抽象产品-产品等级B
class AbstractProductB {
public:
virtual void eat() = 0;
};
//具体产品-产品等级B-产品族1
class ProductB1 :public AbstractProductB
{
public:
void eat() {
cout << "eat Product B1" << endl;
}
};
//具体产品-产品等级B-产品族2
class ProductB2 :public AbstractProductB
{
public:
void eat() {
cout << "eat Product B2" << endl;
}
};
//抽象工厂
class AbstractFactory
{
public:
virtual AbstractProductA* createProductA() = 0;
virtual AbstractProductB* createProductB() = 0;
};
//具体工厂
class ConcreteFactory1:public AbstractFactory
{
public:
AbstractProductA* createProductA()
{
return new ProductA1();
}
AbstractProductB* createProductB()
{
return new ProductB1();
}
};
//具体工厂
class ConcreteFactory2 :public AbstractFactory
{
public:
AbstractProductA* createProductA()
{
return new ProductA2();
}
AbstractProductB* createProductB()
{
return new ProductB2();
}
};
int main()
{
AbstractFactory *cf1=new ConcreteFactory1();
AbstractProductA *pa1 = cf1->createProductA();
AbstractProductB *pb1 = cf1->createProductB();
pa1->use();
pb1->eat();
AbstractFactory *cf2 = new ConcreteFactory2();
AbstractProductA *pa2 = cf2->createProductA();
AbstractProductB *pb2 = cf2->createProductB();
pa2->use();
pb2->eat();
delete cf1, cf2;
delete pa1, pb1, pa2, pb2;
return 0;
}
无论是在现实世界还是软件系统,都存在一些复杂的对象,它们拥有多个足证部分,如汽车,它包括车轮、方向盘、发动机等各种部件。而对于大度哦书用户而言,无需知道这些部件的装配细节,也几乎不会使用单独某个部件,而是使用一辆完成的汽车。
建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。用户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部的具体构造细节。
在软件开发中,也存在大量类似汽车一样的复杂对象,他们拥有一系列成员属性,这些成员属性中有些是引用类型的成员对象。而且这些复杂对象中,还可能存在一些限制条件,如某些属性没有赋值则复杂对象不能作为一个完整的产品使用;有些属性的赋值必须按照某个顺序,一些属性没有赋值之前另外一个属性可能无法复赋值等。
建造者模式:指将一个复杂对象的构造和它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式称为建造者模式。它是将一个复杂对象分解为多个简单的对象,然偶一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
#include
#include
using namespace std;
//产品角色:包含多个组成部件的复杂对象
class Product
{
private:
string partA;
string partB;
string partC;
public:
void setPartA(string partA)
{
this->partA = partA;
}
void setPartB(string partB)
{
this->partB = partB;
}
void setPartC(string partC)
{
this->partC = partC;
}
void show() {
//显示产品特性
cout << partA << endl << partB <<endl<< partC << endl;
}
};
//抽象建造者:包含创建产品各个子部件的抽象方法
class AbstractBuilder
{
protected:
Product *product;
public:
virtual void buildPartA() = 0;
virtual void buildPartB() = 0;
virtual void buildPartC() = 0;
AbstractBuilder() { product = new Product(); }
~AbstractBuilder() { delete product; }
Product* getResult()
{
return product;
}
};
//具体建造者:实现了抽象建造者的接口
class ConcreteBuilder:public AbstractBuilder
{
public:
void buildPartA()
{
product->setPartA("建造 PartA");
}
void buildPartB()
{
product->setPartB("建造 PartB");
}
void buildPartC()
{
product->setPartC("建造 PartC");
}
};
//指挥者:调用建造者中的方法完成对复杂对象的创建
class Director
{
private:
AbstractBuilder *builder;
public:
Director(AbstractBuilder *builder)
{
this->builder = builder;
}
Product* construct()
{
builder->buildPartA();
builder->buildPartB();
builder->buildPartC();
return builder->getResult();
}
};
class Client
{
public:
static void main()
{
AbstractBuilder *builder = new ConcreteBuilder();
Director * director = new Director(builder);
Product *product = director->construct();
product->show();
delete builder, director;
}
};
int main()
{
Client::main();
return 0;
}
对于系统中的某些类来说,只有一个实例很重要,例如,译者系统中可以存在多个打印任务,但是又能有一个正在工作的任务。
让类自身保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。
**单例模式:**确保某一个类只有一个实例,而且自行实例化想整个系统提供这个实例,这个类成为单例类,它提供全局访问的方法。
单例模式的要点有三个:
#include
#include
using namespace std;
//懒汉式单例
/*
该模式的特点是类加载的时候没有生成单例,只有当第一次调用getInstance
方法时采取创建这个单例
*/
class LazySingleton
{
private:
static LazySingleton* instance;
LazySingleton() {}//private避免类在外部被实例化
public:
static LazySingleton* getInstance()
{
if (instance == NULL)
{
instance = new LazySingleton();
}
return instance;
}
};
//饿汉式单例
/*
该模式的特点是类一旦加载就创建一个单例,
保证在调用getInstance方法之前单例就已经存在了
*/
class HungrySingleton
{
private:
static HungrySingleton *instance;
HungrySingleton() {}
public:
static HungrySingleton* getInstance()
{
return instance;
}
};
HungrySingleton *HungrySingleton ::instance= new HungrySingleton();
class Client
{
protected:
static LazySingleton* ls;
static HungrySingleton* hs;
public:
static void main()
{
ls=LazySingleton::getInstance();
hs=HungrySingleton::getInstance();
}
};