目录
简单工厂模式
适用场景
(1)工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
(2)客户端只知道传入工厂类的参数,对于如何创建对象并不关心。
简单工厂模式的优缺点
优点:
(1)实现了对象创建和使用的分离(解耦)。对于对象创建比较复杂情况,使用时不需要考虑其他。
(2)不需要记住具体类名,记住参数即可,减少使用者记忆量。
缺点:
(1)工厂类职责过重,一旦不能工作,系统受到影响。
(2)违反“开闭原则”,添加新产品需要修改工厂逻辑,工厂越来越复杂。
设计与实现
class AbstractFruit {
public:
virtual void ShowName() = 0;
};
class Apple :public AbstractFruit {
public:
void ShowName() {
cout << "我是苹果!" << endl;
}
};
class Banana :public AbstractFruit {
public:
void ShowName() {
cout << "我是香蕉!" << endl;
}
};
class Pear :public AbstractFruit {
public:
void ShowName() {
cout << "我是鸭梨!" << endl;
}
};
enum aa { apple, banana, pear};
class FruitFactor {
public:
static AbstractFruit* createFruit(aa flag) {
switch (flag)
{
case 0:
return new Apple;
case 1:
return new Banana;
case 2:
return new Pear;
default:
return NULL;
}
}
};
void test01() {
FruitFactor* factory = new FruitFactor;
AbstractFruit* fruit = factory->createFruit(apple);
fruit->ShowName();
delete fruit;
fruit = factory->createFruit(banana);
fruit->ShowName();
delete fruit;
fruit = factory->createFruit(pear);
fruit->ShowName();
delete fruit;
}
工厂方法模式
简单工厂模式 + “开闭原则” = 工厂方法模式
设计与实现
class AbstractFruit {
public:
virtual void ShowName() = 0;
};
class Apple :public AbstractFruit {
public:
void ShowName() {
cout << "我是苹果!" << endl;
}
};
class Banana :public AbstractFruit {
public:
void ShowName() {
cout << "我是香蕉!" << endl;
}
};
class Pear :public AbstractFruit {
public:
void ShowName() {
cout << "我是鸭梨!" << endl;
}
};
class abstractFruitFactory {
public:
virtual AbstractFruit* createFruit() = 0;
};
class appleFactory:public abstractFruitFactory {
public:
AbstractFruit* createFruit() {
return new Apple;
}
};
class bananaFactory :public abstractFruitFactory {
public:
AbstractFruit* createFruit() {
return new Banana;
}
};
class pearFactory :public abstractFruitFactory {
public:
AbstractFruit* createFruit() {
return new Pear;
}
};
void test01() {
abstractFruitFactory* factory = NULL;
AbstractFruit* fruit = NULL;
factory = new appleFactory();
fruit = factory->createFruit();
fruit->ShowName();
delete fruit;
delete factory;
factory = new bananaFactory();
fruit = factory->createFruit();
fruit->ShowName();
delete fruit;
delete factory;
factory = new pearFactory();
fruit = factory->createFruit();
fruit->ShowName();
delete fruit;
delete factory;
}
工厂方法模式的总结
传统:如果想创建两个苹果,得具体实例化两个,然后再调用功能,以后再用还得记名字
Apple a;
a.func();
Aplle b;
b.func();
工厂方法模式:可以不用具体一个对象,然后调用
factory = new AppleFactory;
fruit = factory->CreateFruit();//造a
fruit->ShowName();
fruit = factory->CreateFruit();//造b
fruit->ShowName();
抽象工厂模式
设计与实现
class AbstractFruit {
public:
virtual void ShowName() = 0;
};
class ChinaApple :public AbstractFruit {
public:
void ShowName() {
cout << "我是中国苹果!" << endl;
}
};
class ChinaBanana :public AbstractFruit {
public:
void ShowName() {
cout << "我是中国香蕉!" << endl;
}
};
class ChinaPear :public AbstractFruit {
public:
void ShowName() {
cout << "我是中国鸭梨!" << endl;
}
};
class USAApple :public AbstractFruit {
public:
void ShowName() {
cout << "我是USA苹果!" << endl;
}
};
class USABanana :public AbstractFruit {
public:
void ShowName() {
cout << "我是USA香蕉!" << endl;
}
};
class USAPear :public AbstractFruit {
public:
void ShowName() {
cout << "我是USA鸭梨!" << endl;
}
};
class JapanApple :public AbstractFruit {
public:
void ShowName() {
cout << "我是Japan苹果!" << endl;
}
};
class JapanBanana :public AbstractFruit {
public:
void ShowName() {
cout << "我是Japan香蕉!" << endl;
}
};
class JapanPear :public AbstractFruit {
public:
void ShowName() {
cout << "我是Japan鸭梨!" << endl;
}
};
class abstractFactory {
public:
virtual AbstractFruit* createApple() = 0;
virtual AbstractFruit* createBanana() = 0;
virtual AbstractFruit* createPear() = 0;
};
class ChinaFactory:public abstractFactory {
public:
AbstractFruit* createApple(){
return new ChinaApple;
}
AbstractFruit* createBanana() {
return new ChinaBanana;
}
AbstractFruit* createPear() {
return new ChinaPear;
}
};
class USAFactory :public abstractFactory {
public:
AbstractFruit* createApple() {
return new USAApple;
}
AbstractFruit* createBanana() {
return new USABanana;
}
AbstractFruit* createPear() {
return new USAPear;
}
};
class JapanFactory :public abstractFactory {
public:
AbstractFruit* createApple() {
return new JapanApple;
}
AbstractFruit* createBanana() {
return new JapanBanana;
}
AbstractFruit* createPear() {
return new JapanPear;
}
};
void test01() {
abstractFactory* factory = NULL;
AbstractFruit* fruit = NULL;
factory = new ChinaFactory();
fruit = factory->createApple();
fruit->ShowName();
delete fruit;
fruit = factory->createBanana();
fruit->ShowName();
delete fruit;
fruit = factory->createPear();
fruit->ShowName();
delete fruit;
delete factory;
factory = new USAFactory();
fruit = factory->createApple();
fruit->ShowName();
delete fruit;
fruit = factory->createBanana();
fruit->ShowName();
delete fruit;
fruit = factory->createPear();
fruit->ShowName();
delete fruit;
delete factory;
factory = new JapanFactory();
fruit = factory->createApple();
fruit->ShowName();
delete fruit;
fruit = factory->createBanana();
fruit->ShowName();
delete fruit;
fruit = factory->createPear();
fruit->ShowName();
delete fruit;
delete factory;
}
抽象工厂的优缺点
优点:
(1)拥有工厂方法模式的优点
(2)当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
(3)增加新的产品族很方便,无须修改已有系统,符合“开闭原则”。
缺点:
增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了“开闭原则”。
适用场景
(1) 系统中有多于一个的产品族。而每次只使用其中某一产品族。可以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族。
(2) 产品等级结构稳定。设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构。
单例模式
通过单例模式的方法创建的类在当前进程中只有一个实例;
应用场景
配置管理
日志记录
线程池
连接池
内存池
对象池
消息队列
实现步骤
将类的构造方法定义为私有方法
定义一个私有的静态实例
提供一个公有的获取实例的静态方法
涉及知识点
static静态成员数据
static静态成员函数
template模板类
friend友元类
设计与实现
常用实现
模板实现
线程安全
模板
懒汉式(创建时不初始化)
多线程时,是线程不安全的。(多线程可能创建两个)
Singleton.h
#pragma once
namespace mySingleTon {
template<typename T>
class singleTon {
public:
static T* instance() {
if (m_instance == nullptr) {
m_instance = new T();
}
return m_instance;
}
private:
singleTon() {};
singleTon(const singleTon&){}
~singleTon(){}
static T* m_instance;
singleTon<T>& operator =(const singleTon<T>);
};
template<typename T>
T* singleTon<T>::m_instance = nullptr;
};
饿汉式(创建时已经初始化)
多线程时,是线程安全的。
Singleton.h
#pragma once
namespace mySingleTon {
template<typename T>
class singleTon {
public:
static T* instance() {
if (m_instance == nullptr) {
m_instance = new T();
}
return m_instance;
}
private:
singleTon() {};
singleTon(const singleTon&){}
~singleTon(){}
static T* m_instance;
singleTon<T>& operator =(const singleTon<T>);
};
template<typename T>
T* singleTon<T>::m_instance = new singleTon<T> ;
};
A.h
//#pragma once
//#include<string>
//#include<iostream>
//using namespace std;
//
//class A {
//
//public:
// static A* instance() {
// if (m_instance == nullptr) {
// m_instance = new A();
// }
// return m_instance;
// }
// void show() {
// cout << mName << endl;
// }
//private:
// A():mName("A"){}
// A(const A&);
// ~A();
// A & operator=(const A&);
//private:
// static A* m_instance;
// string mName;
//};
//A* A::m_instance = nullptr;
#pragma once
#include<string>
#include<iostream>
#include"Singleton.h"
using namespace std;
class A {
friend class mySingleTon::singleTon<A>;
public:
void show() {
cout << mName << endl;
}
private:
A():mName("A"){}
A(const A&);
~A();
A & operator=(const A&);
private:
static A* m_instance;
string mName;
};
A* A::m_instance = nullptr;
B.h
/*
#pragma once
#include<string>
#include<iostream>
#include"Singleton.h"
using namespace std;
class B {
friend class mySingleTon::singleTon<B>;
public:
static B* instance() {
if (m_instance == nullptr) {
m_instance = new A();
}
return m_instance;
}
void show() {
cout << mName << endl;
}
private:
B() :mName("B") {}
B(const B&);
~B();
B& operator=(const B&);
private:
static B* m_instance;
string mName;
};
B* B::m_instance = nullptr;
*/
#pragma once
#include<string>
#include<iostream>
#include"Singleton.h"
using namespace std;
class B {
friend class mySingleTon::singleTon<B>;
public:
void show() {
cout << mName << endl;
}
private:
B() :mName("B") {}
B(const B&);
~B();
B& operator=(const B&);
private:
static B* m_instance;
string mName;
};
B* B::m_instance = nullptr;
main.c
#include"Singleton.h"
using namespace mySingleTon;
void test() {
//A::instance()->show();
//B::instance()->show();
singleTon<A>::instance()->show();
singleTon<B>::instance()->show();
}
示例
上面是模板,和下面程序没关系,不必一起运行。
main.c
#include <iostream>
using namespace std;
//实现单例步骤
//1.构造函数私有化
//2.增加静态私有的当前类的指针变量
//3.提供静态对外接口,可以让用户获得单例对象
//单例 分为懒汉式 饿汉式
//1.懒汉式(需要的时候才会创建)
class Singleton_lazy {
private:
Singleton_lazy() { cout << "我是懒汉构造!" << endl; }
public:
static Singleton_lazy* getInstance() {
if (pSingleton == NULL) {
pSingleton = new Singleton_lazy;
}
return pSingleton;
}
#if 0
//这样释放不行,万一谁手贱释放,就直接没了,这个权限不能给
static void freeSpace() {
if (pSingleton != NULL) {
delete pSingleton;
}
}
#endif
//如果非要写,可以加个这个,运行完自动释放
class Garbo {
Garbo() {
if (pSingleton != NULL) {
delete pSingleton;
}
}
};
private:
static Singleton_lazy* pSingleton;
static Garbo garbo;
};
//类外初始化
Singleton_lazy* Singleton_lazy::pSingleton = NULL;
//2.饿汉式
class Singleton_hungry {
private:
Singleton_hungry() { cout << "我是饿汉构造!" << endl; }
public:
static Singleton_hungry* getInstance() {
return pSingleton;
}
private:
static Singleton_hungry* pSingleton;
};
//类外初始化
Singleton_hungry* Singleton_hungry::pSingleton = new Singleton_hungry;
void test01() {
Singleton_lazy* p1 = Singleton_lazy::getInstance();
Singleton_lazy* p2 = Singleton_lazy::getInstance();
if (p1 == p2) {
cout << "两个指针指向同一块内存空间,是单例!" << endl;
}
else {
cout << "不是单例模式!" << endl;
}
Singleton_hungry* p3 = Singleton_hungry::getInstance();
Singleton_hungry* p4 = Singleton_hungry::getInstance();
if (p3 == p4) {
cout << "两个指针指向同一块内存空间,是单例!" << endl;
}
else {
cout << "不是单例模式!" << endl;
}
}
#if 0
void test02() {
Singleton_lazy::freeSpace();
}
#endif
int main() {
test01();
cout << "main函数开始执行!" << endl;
return 0;
}