• C++的设计模式


    1. 什么是设计模式
      指的是在特定环境下,人们解决某类重复出现问题的一套成功或有效的解决方案。
      大白话是:在一定环境下,使用固定的套路去解决问题。
    2. 作用:提高软件系统可维护性以及代码的可复用性。
    3. 原则的目的:高内聚低耦合
    4. 高内聚:一个类只做一件事
    5. 低耦合:类和类之间的关系越弱越好。
    6. 这样在后期代码某一部分出错时,只需要修改对应部分,而不需要修改大量和这类关系密切的其他类。减少工作量和出错的概率。
    7. 类的单一原则:类的职责单一,只对外提供一种功能
    8. 类的开闭原则:类的改动是通过增加代码实现的而不是通过修改代码实现的。
    9. 单例模式:分为懒汉式单例模式和饿汉式单例模式
      懒汉式单例模式:static 声明的变量在整个程序退出时释放,所谓的单例就是整个类只有一个全局对象,该对象使用static声明,变为类成员,并且构造函数被私有化,不能被外界随随便便的实例化,这个类成员在外部被赋予一个特殊值,才能声明这个唯一的对象。
      这里在类直接调用类属性(等于特殊值才可以,比如nullptr)instance时,才可以初始化,并且使用public的getInstance函数自动接收这个初始化的属性值,然后在这个函数中唯一的创建这个类的唯一对象。也就是唯一接口供外部使用
      优点是第一次调用的时候才初始化,避免内存浪费。缺点是必须加锁才能保证单例
    #include 
    
    using namespace std;
    
    //懒汉式单例模式
    class SingletonLazy {
    private:
    	static SingletonLazy* instance;
    	// 构造函数私有化, 不让外界利用new创建实例
    	SingletonLazy() {
    		cout << "懒汉式单例模式\n";
    	}
    public:
    	static SingletonLazy* getInstance() {
    	//第一次引用时才被实例化,只有在外部被使用类名进行调用时才初始化我们的唯一对象,没有外部调用那么就不被初始化来占用内存。
    		if (instance == nullptr) {
    			instance = new SingletonLazy;
    		}
    		return instance;
    	}
    };
    
    SingletonLazy* SingletonLazy::instance = nullptr;
    
    //饿汉式单例模式
    class SingletonHungry {
    private:
    	static SingletonHungry* instance2;
    	SingletonHungry() {
    		cout << "饿汉式单例模式\n";
    	}
    public:
    	static SingletonHungry* getInstance() {
    		return instance2;
    	}
    };
    //private下的static变量虽然类外无法通过类直接访问,但是可以类外进行初始化
    //加载时实例化,这里是类外对类内私有唯一对象 instance2进行初始化,其他在类外单独定义的对象不能被初始化,因为无法使用new SingletonHungry语句,也就是调用私有的构造函数。调用不了而对于类内唯一静态对象类内声明类外初始化符合原则,虽然类外初始化,但是使用范围还是类内,所以可以调用该类的私有构造函数对其进行初始化。
    //不管后面是否调用函数,我们唯一的对象都被初始化了。
    SingletonHungry* SingletonHungry::instance2 = new SingletonHungry;
    
    
    int main() {
    	//外部可以直接通过类方法getInstance直接调用获得该唯一的对象
    	cout << SingletonHungry::getInstance << endl;
    	cout << "action: \n";
    	system("pause");
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    1. 饿汉式单例模式:
      缺点:不管用不用,都会初始化,造成内存资源浪费
      优点:不需要加锁,执行效率高,线程安全的
    2. 策略模式
      策略模式:定义一系列的算法,把他们一个个封装起来,并且使他们可相互替换,具体实现与客户端完全分离,客户端只需要操作一个类就可以实现不同功能
      优点:1、减少了算法与使用算法之间的耦合度。 2、测试方便,每个算法都有自己的类,只要测试自己接口就行了,不影响其他算法
      每一个策略都是一个算法
    #include 
    #include 
    
    using namespace std;
    //策略抽象类,定义所有支持的算法的公共接口
    class CashSuper {
    public:
    	virtual double acceptCash(double money) {
    		return money;
    	}
    };
    //具体策略类
    class NormalFee :CashSuper {
    public:
    	double acceptCash(double money) {
    		return money;
    	}
    };
    class DiscountFee :CashSuper {
    public:
    	float discountNum;
    public:
    	DiscountFee(float discountNum) {
    		this->discountNum = discountNum;
    		cout << endl;
    	}
    	double acceptCash(double money) {
    		return money * this->discountNum;
    	}
    };
    
    class ReturnFee :CashSuper {
    public:
    	int fill;
    	int send;
    public:
    	ReturnFee(int fill, int send) :fill(fill), send(send) {}
    	double acceptCash(double money) {
    		if (money > this->fill) {
    			return money - send;
    		}
    		return money;
    	}
    };
    //用一个具体策略来配置维护一个对策略对象的引用
    CashContext 为具体算法和客户端之间的桥梁
    //客户端可以根据不同的需求通过CashContext获得不同的结果
    class CashContext {
    private:
    	CashSuper* cs = nullptr;
    public:
    	CashContext(int type) {
    		switch (type) {
    		case 0:
    			cs = (CashSuper*) new NormalFee;
    			break;
    		case 1:
    			cs = (CashSuper*)new DiscountFee(0.8);
    			break;
    		case 2:
    			cs = (CashSuper*) new DiscountFee(0.7);
    			break;
    		case 3:
    			cs = (CashSuper*) new DiscountFee(0.5);
    			break;
    		case 4:
    			cs = (CashSuper*) new ReturnFee(300, 100);
    			break;
    		}
    	}
    	//根据不同策略对象来实现不同结果
    	double getResult(double money) {
    		return cs->acceptCash(money);
    	}
    };
    int main()
    {
    	
    	//实例化打八折类
    	CashContext cc(1);
    	//获取打折后金额
    	double res = cc.getResult(100);
    	cout << res << endl;
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86

    总结,如果将满减和打8折以及原价放一起(同一个类),假如打折或者原价代码出错,也会导致满减代码无法运行,也就无法实现满减功能,所以降低各个小功能之间的耦合度势在必行。,各个算法单独封装成一个个类,就是一个个不同的策略。

    具体C++设计模式参考教程:https://blog.csdn.net/qq_46423987/article/details/126702565

  • 相关阅读:
    Sping-AOP切面相关操作
    CSS 设置垂直居中
    肖sir__mysql之做题总结
    2022.9.20 go语言课程作业
    Pytest插件
    【Hadoop】- MapReduce & YARN的部署[8]
    vue中 table中的treeselect 下拉框不显示
    asp.net学校门户网站系统VS开发sqlserver数据库web结构c#编程计算机网页项目
    EDCircles: A real-time circle detector with a false detection control 翻译
    阿里云linux服务器:能ping通但是无法访问tomcat
  • 原文地址:https://blog.csdn.net/m0_54342473/article/details/127670356