设计模式在面试中有可能会遇到,主要考察单例模式与工厂模式,其中单例模式最重要,必须会写。
一、单例模式
作用:
单例模式的作用是保证一个类只有一个实例,并提供一个访问它的全局访问点,使得系统中只有唯一的一个对象实例。
实现思路:
将构造函数、拷贝构造函数和赋值构造函数全都声明为
private
,防止在类外构造实例,并在类内提供一个全局访问点,返回在类内部唯一构造的实例。
分类:
单例模式分两种,饿汉模式与懒汉模式,因为面试时间有限,代码太长又不便记忆,我总结了两个比较短的版本,供大家学习参考。
1、饿汉模式
在类产生的时候就创建好实例,这是一种空间换时间的做法。
#include <iostream>
using namespace std;
class Singleton {
private:
Singleton() { cout << "Singleton Create." << endl; } //构造函数
Singleton(Singleton const&); //拷贝构造
Singleton& operator=(Singleton const&); //赋值构造
~Singleton() { cout << "Singleton Destroy." << endl; } //析构函数
static Singleton instance;
public:
static Singleton* getInstance() {
return &instance;
}
};
//下面这个静态成员变量在类加载的时候就已经初始化好了
Singleton Singleton::instance;
int main()
{
Singleton *p = Singleton::getInstance();
return 0;
}
2、懒汉模式
第一次用到类的实例的时候才会去实例化。面试官可能会问懒汉模式是否线程安全?答否,因为多个线程同时创建实例时会有多个实例,解决方法是加锁。
#include <iostream>
using namespace std;
class Singleton {
private:
Singleton() { cout << "Singleton Create." << endl; }
Singleton(Singleton const&);
Singleton& operator=(Singleton const&);
~Singleton() { cout << "Singleton Destroy." << endl; }
public:
static Singleton* getInstance() {
static Singleton instance;
return &instance;
}
};
int main()
{
Singleton *p = Singleton::getInstance();
return 0;
}
注意两种模式的不同之处,其实只有三行。
二、工厂模式
工厂模式主要有三种:简单工厂模式、工厂方法模式、抽象工厂模式。
1、简单工厂模式
简单工厂是工厂模式最简单的一种实现,对于不同产品的创建定义一个工厂类,将产品的类型作为参数传入到工厂的创建函数,根据类型分支选择不同的产品构造函数。
//简单工厂模式
typedef enum productType {
TypeA,
TypeB,
TypeC
} productTypeTag;
class Product {
public:
virtual void show() = 0;
virtual ~Product() = 0;
};
class ProductA :public Product {
public:
void show() {
cout << "ProductA" << endl;
}
~ProductA() {
cout << "~ProductA" << endl;
}
};
class ProductB :public Product {
public:
void show() {
cout << "ProductB" << endl;
}
~ProductB() {
cout << "~ProductB" << endl;
}
};
class ProductC :public Product {
public:
void show() {
cout << "ProductC" << endl;
}
~ProductC() {
cout << "~ProductC" << endl;
}
};
class Factory {
public:
Product* createProduct(productType type) {
switch (type) {
case TypeA:
return new ProductA();
case TypeB:
return new ProductB();
case TypeC:
return new ProductC();
default:
return nullptr;
}
}
};
2、工厂方法模式
其实这才是正宗的工厂模式,简单工厂模式只是一个简单的对创建过程封装。工厂方法模式在简单工厂模式的基础上增加对工厂的基类抽象,不同的产品创建采用不同的工厂创建(从工厂的抽象基类派生),这样创建不同的产品过程就由不同的工厂分工解决:FactoryA专心负责生产ProductA,FactoryB专心负责生产ProductB,FactoryA和FactoryB之间没有关系;如果到了后期,如果需要生产ProductC时,我们则可以创建一个FactoryC工厂类,该类专心负责生产ProductC类产品。
该模式相对于简单工厂模式的优势在于:便于后期产品种类的扩展。
#include <iostream>
using namespace std;
//工厂方法模式
typedef enum ProductTypeTag {
TypeA,
TypeB,
TypeC
}PRODUCTTYPE;
class Product { //产品抽象基类
public:
virtual void Show() = 0;
};
class ProductA : public Product //产品A
{
public:
void Show()
{
cout<<"I'm ProductA"<<endl;
}
};
class ProductB : public Product //产品B
{
public:
void Show()
{
cout<<"I'm ProductB"<<endl;
}
};
class Factory //工厂类
{
public:
virtual Product *createProduct()=0;
};
class FactoryA : public Factory{ //工厂A
public:
Product *createProduct(){
return new ProductA();
}
};
class FactoryB : public Factory{ //工厂B
public:
Product *createProduct(){
return new ProductB();
}
};
class FactoryC : public Factory{ //工厂C
public:
Product *createProduct(){
return new ProductC();
}
};
int main()
{
Factory *factoryA = new FactoryA();
Product *productA = factoryA->createProduct();
productA->Show();
Factory *factoryB = new FactoryB();
Product *productB = factoryB->createProduct();
productB->Show();
if (factoryA)
{
delete factoryA;
factoryA = NULL;
}
if (factoryB)
{
delete factoryB;
factoryB = NULL;
}
if (productA)
{
delete productA;
productA = NULL;
}
if (productB)
{
delete productB;
productB = NULL;
}
return 0;
}
3、抽象工厂模式
抽象工厂模式对工厂方法模式进行了更加一般化的描述。工厂方法模式适用于产品种类结构单一的场合,为一类产品提供创建的接口;而抽象工厂方法适用于产品种类结构多的场合,就是当具有多个抽象产品类型时,抽象工厂便可以派上用场。
抽象工厂模式更适合实际情况,受生产线所限,让低端工厂生产不同种类的低端产品,高端工厂生产不同种类的高端产品。
#include <iostream>
using namespace std;
//抽象工厂模式
class ProductA //A基类
{
public:
virtual void Show() = 0;
};
class ProductA1 : public ProductA //A类低端产品
{
public:
void Show()
{
cout<<"I'm ProductA1"<<endl;
}
};
class ProductA2 : public ProductA //A类高端产品
{
public:
void Show()
{
cout<<"I'm ProductA2"<<endl;
}
};
class ProductB //B基类
{
public:
virtual void Show() = 0;
};
class ProductB1 : public ProductB //B类低端产品
{
public:
void Show()
{
cout<<"I'm ProductB1"<<endl;
}
};
class ProductB2 : public ProductB //B类高端产品
{
public:
void Show()
{
cout<<"I'm ProductB2"<<endl;
}
};
class Factory
{
public:
virtual ProductA *CreateProductA() = 0;
virtual ProductB *CreateProductB() = 0;
};
class Factory1 : public Factory //1号工厂用于生产低端产品
{
public:
ProductA *CreateProductA()
{
return new ProductA1();
}
ProductB *CreateProductB()
{
return new ProductB1();
}
};
class Factory2 : public Factory //2号工厂用于生产高端产品
{
ProductA *CreateProductA()
{
return new ProductA2();
}
ProductB *CreateProductB()
{
return new ProductB2();
}
};
int main()
{
Factory *factory1 = new Factory1();
ProductA *productA1 = factory1->CreateProductA();
ProductB *productB1 = factory1->CreateProductB();
productA1->Show();
productB1->Show();
Factory *factory2 = new Factory2();
ProductA *productA2 = factory2->CreateProductA();
ProductB *productB2 = factory2->CreateProductB();
productA2->Show();
productB2->Show();
if (factory1)
{
delete factory1;
factory1 = NULL;
}
if (productA1)
{
delete productA1;
productA1= NULL;
}
if (productB1)
{
delete productB1;
productB1 = NULL;
}
if (factory2)
{
delete factory2;
factory2 = NULL;
}
if (productA2)
{
delete productA2;
productA2 = NULL;
}
if (productB2)
{
delete productB2;
productB2 = NULL;
}
}
工厂模式代码太长,面试真的会要求写吗?我还没遇到过,尽量先理解吧。
其他设计模式被问到的概率没那么大,暂时先不写了。
这面试也太难了点,表示看不太懂2333
哈哈,我也就记住了单例模式,面试不一定会问。