设计模式: 简单工厂模式 工厂方法模式 抽象工厂模式 单例模式

阅读: 评论:0

设计模式: 简单工厂模式 工厂方法模式 抽象工厂模式 单例模式

设计模式: 简单工厂模式 工厂方法模式 抽象工厂模式 单例模式

目录

  • 简单工厂模式
    • 适用场景
    • 简单工厂模式的优缺点
    • 设计与实现
  • 工厂方法模式
    • 设计与实现
    • 工厂方法模式的总结
  • 抽象工厂模式
    • 设计与实现
    • 抽象工厂的优缺点
    • 适用场景
  • 单例模式
    • 应用场景
    • 实现步骤
    • 涉及知识点
    • 设计与实现
      • 模板
        • 懒汉式(创建时不初始化)
        • 饿汉式(创建时已经初始化)
      • 示例

简单工厂模式

适用场景

(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();
}
#endifint main() {test01();cout << "main函数开始执行!" << endl;return 0;
}

本文发布于:2024-02-02 23:48:44,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170688892147271.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:模式   工厂   抽象   简单   方法
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23