自学设计模式(类图、设计原则、单例模式 - 饿汉/懒汉)

这篇具有很好参考价值的文章主要介绍了自学设计模式(类图、设计原则、单例模式 - 饿汉/懒汉)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

设计模式需要用到面向对象的三大特性——封装、继承、多态(同名函数具有不同的状态)

UML类图 eg.—— 描述类之间的关系(设计程序之间画类图)

自学设计模式(类图、设计原则、单例模式 - 饿汉/懒汉),设计模式

 +: public; #: protected; -: private; 下划线: static

属性名:类型(=默认值)

方法和变量分开-------

虚函数斜体,纯虚函数在虚函数类型后=0,并且类名斜体

类与类之间的关系:

1. 继承关系(空心三角形实线,箭头指父类)

2. 关联关系(单项关联、双向关联、自关联 - 链表)用带箭头和不带箭头的实现

3. 聚合关系(整体与部分的关系,整体析构部分不析构)空心菱形实线链接,指向整体

4. 组合关系(整体析构部分析构)实心菱形实线链接

5. 依赖关系(使用关系)带箭头的虚线,指向被依赖方

类之间的关系强弱:继承(泛化)>组合>聚合>关联>依赖(类图按类间最强关系就可)

设计模式三原则

单一职责原则(面向对象):

使得类的功能尽量单一,方便管理维护,避免类的臃肿。

开放封闭原则:

对于扩展是开放的,对于修改是封闭的,增加程序可维护性可扩展性。

依赖转换原则:

高层模块不应该依赖低层模块(应用程序不直接调用API),两个都应该依赖抽象。

抽象不依赖细节,细节应该依赖抽象。(里氏代换原则)

单例模式和任务队列(类的对象只能创建出一个)

一个项目中,全局范围内,某个类的实例有且仅有一个,通过这个实例向其他模块提供数据的全局访问。(简介访问实现对于变量的保护)

将类的默认构造函数和拷贝构造函数设为private,或者将两个函数=delete;

使类无法在外面创建对象,只能通过类名访问静态属性或者方法;

懒汉模式和饿汉模式

饿汉模式——定义类的时候创建单例对象(多线程下没有线程安全问题)

// 饿汉模式
#include <bits/stdc++.h>
using namespace std;

class A{
public:
	A(const A& a) = delete;
	A& operator =(const A& a) = delete;
	static A* get(){
		return num;
	}
	print(){
		cout<<"单例模式的唯一实例";
	}
private:
	A() = default; // 默认构造 
	static A* num;
};

A* A::num = new A;

int main(){
	A* a = A::get();
	a->print(); 
	return 0;
} 

懒汉模式——什么时候使用单例对象再去创建实例(多线程下存在线程安全问题)

// 懒汉模式
#include <bits/stdc++.h>
using namespace std;

class A{
public:
	A(const A& a) = delete;
	A& operator =(const A& a) = delete;
	static A* get(){
        num = new A;
		return num;
	}
	print(){
		cout<<"单例模式的唯一实例";
	}
private:
	A() = default; // 默认构造 
	static A* num;
};

A* A::num = nullptr;

int main(){
	A* a = A::get();
	a->print(); 
	return 0;
} 

懒汉模式的线程安全问题

可以通过双重检查锁定解决懒汉模式的线程安全问题:1. 互斥锁(导致效率低) 2. 实例创建判定

// 懒汉模式
#include <bits/stdc++.h> 
using namespace std;

class A{
public:
	A(const A& a) = delete;
	A& operator =(const A& a) = delete;
	static A* get(){ // first check
		if(num==nullptr){
			lk.lock();
			if(num==nullptr)num = new A; // second check 
			lk.unlock();
		}
		return num;
	}
	print(){
		cout<<"单例模式的唯一实例";
	}
private:
	A() = default; // 默认构造 
	static A* num;
	static mutex lk;
};

A* A::num = nullptr;
mutex A::lk;

int main(){
	A* a = A::get();
	a->print(); 
	return 0;
} 

通过原子变量(atomic - 底层控制机器指令执行顺序)解决双重检查锁定的问题;放置底层的机器指令不按理想顺序执行

// 懒汉模式
#include <bits/stdc++.h> 
using namespace std;

class A{
public:
	A(const A& a) = delete;
	A& operator =(const A& a) = delete;
	static A* get(){ // first check
		A* cur = task.load();
		if(cur==nullptr){
			lk.lock();
			cur = task.load();
			if(cur==nullptr){
				cur = new A; // second check
				task.store(cur);
			} 
			lk.unlock();
		}
		return cur;
	}
	print(){
		cout<<"单例模式的唯一实例";
	}
private:
	A() = default; // 默认构造 
	static A* num;
	static mutex lk;
	static atomic<A*> task;
};

A* A::num = nullptr;
mutex A::lk;
atomic<A*> A::task;

int main(){
	A* a = A::get();
	a->print(); 
	return 0;
} 

使用静态局部对象解决线程安全问题

#include <bits/stdc++.h> 
using namespace std;

class A{
public:
	A(const A& a) = delete;
	A& operator =(const A& a) = delete;
	static A* get(){ // first check
		static A a;
		return &a; 
	}
	print(){
		cout<<"单例模式的唯一实例";
	}
private:
	A() = default; // 默认构造 
};

int main(){
	A* a = A::get();
	a->print(); 
	return 0;
} 

并发执行应当等待变量完成初始化;

总结

1. 饿汉模式不存在线程安全问题

2. 懒汉模式通过双重检查锁定+原子变量或者静态局部对象(简单)可以解决线程安全问题       文章来源地址https://www.toymoban.com/news/detail-678150.html

实践(多线程模式下的任务模型)

#include <bits/stdc++.h>
using namespace std;


// 饿汉模式
#include <bits/stdc++.h>
using namespace std;

class A{
public:
	A(const A& a) = delete;
	A& operator =(const A& a) = delete;
	static A* get(){
		return num;
	}
	print(){
		cout<<"单例模式的唯一实例";
	}
	
	bool isempty(){
		lock_guard<mutex> locker(m_mutex);
		return mis.empty(); 
	}
	
	void add_m(int node){
		lock_guard<mutex> locker(m_mutex);
		mis.push(node);
	}
	
	bool minus_m(){
		lock_guard<mutex> locker(m_mutex);
		if(mis.empty())return false;
		else{
			mis.pop();
		}
		return true;
	}
	
	int get_m(){
		lock_guard<mutex> locker(m_mutex);
		if(mis.empty())return -1;
		return mis.front();	
	}
private:
	A() = default; // 默认构造 
	static A* num;
	queue<int> mis;
	mutex m_mutex;
};

A* A::num = new A;

int main(){
	A *a = A::get();
	
	// 生产者
	thread t1([=](){
		for(int i = 0 ; i<10 ; i++){
			a->add_m(i+100);
			cout<<"push data: "<<i+100<<" "<<"threadId: "<<this_thread::get_id()<<endl;
			this_thread::sleep_for(chrono::milliseconds(500));
		} 
	});

	// 消费者 
	thread t2([=](){
		this_thread::sleep_for(chrono::milliseconds(100));
		while(!a->isempty()){
			int cur = a->get_m();
			cout<<"take data: "<<cur<<" "<<"threadId: "<<this_thread::get_id()<<endl;
			a->minus_m();
			this_thread::sleep_for(chrono::milliseconds(1000));
		} 
	});
	
	// 阻塞主线程 
	t1.join();
	t2.join();
	
	return 0;
} 

到了这里,关于自学设计模式(类图、设计原则、单例模式 - 饿汉/懒汉)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式——C++11实现单例模式(饿汉模式、懒汉模式),与单例的进程

    本文将介绍单例模式,使用C++11实现多个版本的单例模式,分析各自的优缺点。最后提及如何实现一个单例的进程。 单例模式属于创建型模式,提供了一种创建对象的方式。 单例模式确保一个类只有一个实例。通过一个类统一地访问这个实例。 思想:将构造函数设置为私有

    2024年02月09日
    浏览(50)
  • 设计模式第一课-单例模式(懒汉模式和饿汉模式)

    个人理解:单例模式实际就是通过类加载的方式获取到一个对象,并且保证这个对象在使用中只有一个,不允许再次被创建 1、懒汉模式的基础写法 代码解释: (1)、编写LazySingleton类的时候,需要将成员属性设定为static,这样才会是类属性 (2)、重写构造方法,将其设置

    2024年02月05日
    浏览(43)
  • 24种设计模式之单例模式(饿汉式、懒汉式)

    单例模式( Singleton Pattern )是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点。单例模式是创建型模式。单例模式在现实生活中应用也非常广泛,例如,总统,班主任等。J2EE标准中的ServletContext 、ServletContextConfig 等、Spring框架应用中的。 特点:构造方

    2024年02月07日
    浏览(47)
  • Java中单例(单态、原子)设计模式(饿汉式/懒汉式)

    先看文章目录,大致了解知识点结构,直接点击文章目录可以跳转到文章指定位置。 设计模式就是设计出来的固定问题的解决方法,描述了在软件设计过程中的一些不断重复发生的问题和解决方案。遇到类似问题的时候可以直接使用现成的模式方案。 ①单例模式中一个类只

    2024年02月04日
    浏览(42)
  • Java设计模式之单例模式详解(懒汉式和饿汉式)

    在开发工作中,有些类只需要存在一个实例,这时就可以使用单例模式。Java中的单例模式是一种常见的设计模式,它确保一个类只有一个实例,并提供全局访问点。下面来介绍一下两种常见的单例模式:懒汉式和饿汉式。 懒汉式属于一种延迟加载的单例模式,它的特点是在

    2024年02月15日
    浏览(45)
  • 单例设计模式精讲(饿汉式和懒汉式实现的重要方法)

    目录 什么叫做单例模式? 饿汉式和懒汉式的区别? 饿汉式-方式1(静态变量方式) 饿汉式-方式2(静态代码块方式) 懒汉式-方式1(线程不安全) 懒汉式-方式2(线程安全) 懒汉式-方式3(双重检查锁) 懒汉式-方式4(静态内部类方式) 什么叫做单例模式?         涉

    2024年02月12日
    浏览(67)
  • Java设计模式之创建型-单例模式(UML类图+案例分析)

    目录 一、基础概念 二、UML类图 三、角色设计 四、案例分析 4.1、饿汉模式 4.2、懒汉模式(线程不安全) 4.3、懒汉模式(线程安全) 4.4、双重检索模式 4.5、静态内部类 4.6、枚举  五、总结 单例模式确保一个类只有一个实例,提供一个全局访问点。一般实现方式是把构造函

    2024年02月13日
    浏览(46)
  • 【Java|多线程与高并发】设计模式-单例模式(饿汉式,懒汉式和静态内部类)

    设计模式是一种在软件开发中常用的解决复杂问题的方法论。它提供了一套经过验证的解决方案,用于解决特定类型问题的设计和实现。设计模式可以帮助开发人员提高代码的可重用性、可维护性和可扩展性。 设计模式有很多,本文主要介绍单例模式. 单例模式是一种创建型设

    2024年02月11日
    浏览(54)
  • 设计模式(1) - UML类图

    从这一节开始,我们将一起学习设计模式。我们的学习目标是什么呢? 了解常用设计模式以及它们的使用场景; 分析实际工程中设计模式的使用,揣摩实际意图,了解作者设计思路; 尝试运用设计模式迭代、重构自己的代码; 提升软件架构设计思路。 最近在阅读 Android 源

    2024年02月09日
    浏览(35)
  • 【设计模式】二、UML 类图概述

    UML类图:类(对象)本身的组成和类(对象)之间的各种静态关系 依赖、泛化(继承)、实现、关联、聚合与组合 类中用到了对方,那么他们之间就存在依赖关系 类中用到了对方 如果是类的成员属性 如果是方法的返回类型 是方法接收的参数类型 方法中使用到 泛化关系实际上就

    2024年02月09日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包