面向对象的三大特性:封装、继承、多态
追求:高内聚,低耦合
1、Factory模式:
引入原因:为了提高内聚,降低耦合,会抽象出一些类的公共接口形成抽象基类或接口,在每次用到子类时都要使用new ***,这就要求知道子类的名称,同时也影响了程序的扩展性和维护变得困难。另一种情况时在父类中并不知道要实例化哪一个具体的子类,例如a中用到类B,但B是一个抽象类
Factory功能:1)定义创建对象的接口,封装了对象的创建;
2)使得具体化类的工作延迟到了子类中。
例如:
product.h
#ifndef _PRODUCT_H_
#define _PRODUCT_H_
class Product
{
public:
virtual ~Product() = 0; //纯虚函数, ①纯虚函数没有函数体;②最后面的“=0”并不表示函数返回值为0,它只起形式上的作用,告诉编译系统“这是纯虚函数”; ③这是一个声明语句,最后应有分号。不用实现,但在子类中必须实现。
protected:
Product();
};
class ConcreteProduct:public Product
{
public:
~ConcreteProduct();
ConcreteProduct();
};
//-----------------------product.cpp-----------------------
Product::Product() { }
Product::~Product() { }
ConcreteProduct::ConcreteProduct()
{
cout<<"ConcreteProduct...."<<endl;
}
ConcreteProduct::~ConcreteProduct() { }
//-----------------------factory.h------------------
#ifndef _FACTORY_H_
#define _FACTORY_H_
class Product;
class Factory
{
public:
virtual ~Factory() = 0;
virtual Product* CreateProduct() = 0;
protected:
Factory();
};
class ConcreteFactory:public Factory
{
public:
~ConcreteFactory();
ConcreteFactory();
Product* CreateProduct();
};
#endif //~_FACTORY_H_
//---------------factory.cpp---------
#include "Factory.h"
#include "Product.h"
#include <iostream>
using namespace std;
Factory::Factory() { }
Factory::~Factory() { }
ConcreteFactory::ConcreteFactory()
{
cout<<"ConcreteFactory....."<<endl;
}
ConcreteFactory::~ConcreteFactory() { }
Product* ConcreteFactory::CreateProduct()
{
return new ConcreteProduct();
}
2、AbstractFactory
对不同类提供一个对象创建的接口时,factory无法使用。
//---------------------Product.h ----------------
#ifndef _PRODUCT_H_
#define _PRODUCT_H_
class AbstractProductA
{
public:
virtual ~AbstractProductA();
protected:
AbstractProductA();
};
class AbstractProductB
{
public:
virtual ~AbstractProductB();
protected:
AbstractProductB(); private:
};
class ProductA1:public AbstractProductA
{
public:
ProductA1();
~ProductA1();
};
class ProductA2:public AbstractProductA
{
public:
ProductA2();
~ProductA2();
};
class ProductB1:public AbstractProductB
{
public:
ProductB1();
~ProductB1();
};
class ProductB2:public AbstractProductB
{
public:
ProductB2();
~ProductB2();
};
//-----------------------------AbstractFactory.h ------------------------------
#ifndef _ABSTRACTFACTORY_H_
#define _ABSTRACTFACTORY_H_
class AbstractProductA;
class AbstractProductB;
class AbstractFactory
{
public:
virtual ~AbstractFactory();
virtual AbstractProductA*
CreateProductA() = 0;
virtual AbstractProductB*
CreateProductB() = 0;
protected:
AbstractFactory();
private:
};
class ConcreteFactory1:public AbstractFactory
{
public:
ConcreteFactory1();
~ConcreteFactory1();
AbstractProductA* CreateProductA(){ return new ProductA1(); };
AbstractProductB* CreateProductB(){ return new ProductB1(); };
};
class ConcreteFactory2:public AbstractFactory
{
public:
ConcreteFactory2();
~ConcreteFactory2();
AbstractProductA* CreateProductA(){return new ProductA2(); };
AbstractProductB* CreateProductB(){return new ProductB2(); };
}
3、Singleton模式
Singletom主要解决的是创建一个唯一的变量,在基于对象的设计中,可以使用全局变量来实现,但是面向对象中,只能通过Singleton来实现了。
通过一个static变量来记录唯一的实例,同时也通过static接口来获得这个实例。
Singleton 不可以被实例化,因此我们将其构造函数声明为 protected 或者直接声明为 private。
//--------------------Singleton.h --------------------
#ifndef _SINGLETON_H_
#define _SINGLETON_H_
#include <iostream>
using namespace std;
class Singleton
{
public:
static Singleton* Instance();
protected:
Singleton();
private:
static Singleton* _instance;
};
//---------------------Singleton.cpp--------------------------
#include "Singleton.h"
#include <iostream>
using namespace std;
Singleton* Singleton::_instance = 0;
Singleton::Singleton()
{
cout<<"Singleton...."<<endl;
}
Singleton* Singleton::Instance()
{
if (_instance == 0)
{
_instance = new Singleton();
}
return _instance;
}
//---------------main.cpp --------------
#include "Singleton.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
Singleton* sgn = Singleton::Instance();
return 0;
}
4、Builder模式
当我们要创建的对象很复杂的时候(通常是由很多其他的对象组合而成),我们要将复杂对象的创建过程和这个对象的表示(展示)分离开来,这样做的好处就是通过一步步的进行复杂对象的构建,由于在每一步的构造过程中可以引入参数,使得经过相同的步骤创建最后得到的对象的展示不一样。
// -------------------Product.h------------------------
class Product
{
public:
Product();
~Product();
void ProducePart();
};
class ProductPart
{
public:
ProductPart();
~ProductPart();
ProductPart* BuildPart();
};
//---------------- Builder.h ------------------------------
class Product;
class Builder
{
public:
virtual ~Builder();
virtual void BuildPartA(const string& buildPara) = 0;
virtual void BuildPartB(const string& buildPara) = 0;
virtual void BuildPartC(const string& buildPara) = 0;
virtual Product* GetProduct() = 0;
protected:
Builder();
};
class ConcreteBuilder:public Builder
{
public:
ConcreteBuilder();
~ConcreteBuilder();
void BuildPartA(const string& buildPara);
void BuildPartB(const string& buildPara);
void BuildPartC(const string& buildPara);
Product* GetProduct();
}
//--------------Director.h ------------------------
#ifndef _DIRECTOR_H_
#define _DIRECTOR_H_
class Builder;
class Director
{
public:
Director(Builder* bld);
~Director();
void Construct();
private:
Builder* _bld;
};
//------------------------Director.cpp --------------------
#include "director.h"
#include "Builder.h"
Director::Director(Builder* bld)
{
_bld = bld;
}
Director::~Director() { }
void Director::Construct()
{
_bld->BuildPartA("user-defined");
_bld->BuildPartB("user-defined");
_bld->BuildPartC("user-defined");
}
//--------------------main.cpp---------------------------------
#include "Builder.h"
#include "Product.h"
#include "Director.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
Director* d = new Director(new ConcreteBuilder());
d->Construct();
return 0;
}
5 Prototype 模式
实现了自我复制功能,相比于C++的拷贝构造函数的深拷贝、浅拷贝较为简单易懂,而且不易出错。深拷贝即对类中的new的资源重新new,而不是简单的赋值。默认的拷贝构造函数是浅拷贝。
Prototype 模式提供了一个通过已存在对象进行新对象创建的接口(Clone),Clone()实现和具体的实现语言相关,在 C++中我们将通过拷贝构造函数实现之
//-----------------Prototype.h ---------------------------
#ifndef _PROTOTYPE_H_
#define _PROTOTYPE_H_
class Prototype
{
public:
virtual ~Prototype();
virtual Prototype* Clone() const = 0;
protected:
Prototype();
};
class ConcretePrototype:public Prototype
{
public:
ConcretePrototype();
ConcretePrototype(const ConcretePrototype& cp);
~ConcretePrototype();
Prototype* Clone() const; //常成员函数,函数中不能改变成员变量的值
};
//------------------------------Prototype.cpp ----------------------------
#include "Prototype.h"
#include <iostream>
using namespace std;
Prototype::Prototype()
{
}
Prototype::~Prototype()
{
}
Prototype* Prototype::Clone() const
{
return 0;
}
ConcretePrototype::ConcretePrototype()
{
}
ConcretePrototype::~ConcretePrototype()
{
}
ConcretePrototype::ConcretePrototype(const ConcretePrototype& cp)
{
cout<<"ConcretePrototype copy ..."<<endl;
}
Prototype* ConcretePrototype::Clone() const
{
return new ConcretePrototype(*this);
}
//---------------main.cpp ------------------
#include "Prototype.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
Prototype* p = new ConcretePrototype();
Prototype* p1 = p->Clone();
return 0;
}