当前位置: 首页 > news >正文

设计模式-1 概念 创建型模式

一、设计模式概念

1、设计模式分类(23种)

分类

成员

创建模式(5种)

提供创建对象的机制,提升已有代码的灵活性和可复用性;

常用:

1、单例;

2、工厂:(工厂方法、抽象工厂);

3、建造者;

不常用:

1、原型模式;

结构模式(7种)

如何将对象和类组装成较大的结构,并同时保持结构的灵活和高效;

常用:

1、代理;

2、桥接;

3、装饰;

4、适配器;

不常用:

1、外观;

2、组合;

3、享元;

行为模式(11种)

负责对象间的高效沟通和职责传递委派;

常用:

1、观察者;

2、模板方法;

3、策略;

4、责任链;

5、迭代器;

6、状态;

不常用:

1、访问者;

2、备忘录;

3、命令;

4、解释器;

5、中介者;

2、六大设计原则(SOLID)

名称

定义

单一职责原则

Single Responsibitiyty Principle

1、一个类(一个模块)只管一件事;

2、粒度小,功能单一;

开闭原则

Open Close Principle

1、对扩展开放,对修改封闭(是所有设计模式的最核心目标)

优点:

2、新老逻辑解耦,添加需求不会影响旧的逻辑;

3、改动成本低,不需要改原有逻辑;

4、提高代码的可扩展性和稳定性;

里氏替换原则

Liskov Substitution ​Principle

1、出现在多态中:接口中的方法可以被多个类实现,使用不同的实现类调用这个方法;

2、示例:interface = new Class();

3、实际执行的是Class里面的方法;

接口分离原则

Interface Segregation ​Principle

1、应该创建职责少的interface;

依赖倒置原则

Dependence Inversion ​Principle

1、高层模块不应该直接依赖低层模块,它们都应该直接依赖抽象;

2、高层依赖interface,低层实现interface;

迪米特法则

Least Knowledge ​Principle

1、类知道的越少越好;

2、多使用中间人;

二、创建型设计模式

创建型模式说明:创建对象的机制,提升已有代码的灵活性和复用性;

一、单例

一个类在运行的时候,只有一个实例。

使用方法:

保证一个类只有一个实例。

为这个实例提供一个全局访问点。

1、饿汉单例

package creationPattern.Singleton;/*** 单例模式-饿汉式* 特点:*      1、在类加载的时候创建【静态的私有的】对象,保证创建过程是线程安全的;*      2、不支持延时加载,获取对象的速度快;*      3、但如果对象比较大,而且一直没使用,就会浪费内存;*/
public class Singleton_01 {// 1.私有构造方法private Singleton_01() {}// 2.创建私有的静态的全局对象private static Singleton_01 instance = new Singleton_01();// 3.给外部提供全局访问点public static Singleton_01 getInstance() {return instance;}
}

2、懒汉单例 - 线程不安全

package creationPattern.Singleton;/*** 单例模式-懒汉式*      1、支持延时加载,调用get方法时才会创建对象;*      2、线程不安全*/
public class Singleton_02 {// 1.私有构造方法private Singleton_02() {}// 2.创建私有的静态的全局对象private static Singleton_02 instance;// 3.给外部提供全局访问点public static Singleton_02 getInstance() {if (null == instance)instance = new Singleton_02();return instance;}
}

3、懒汉单例 - 线程安全

package creationPattern.Singleton;/*** 单例模式-懒汉式*      1、支持延时加载,调用get方法时才会创建对象;*      2、线程安全,但是因为加了锁,导致并发度降低;*/
public class Singleton_03 {// 1.私有构造方法private Singleton_03() {}// 2.创建私有的静态的全局对象private static Singleton_03 instance;// 3.给外部提供全局访问点// 添加同步锁public static synchronized Singleton_03 getInstance() {if (null == instance)instance = new Singleton_03();return instance;}
}

4、懒汉单例 - 双重校验:代码相对复杂

package creationPattern.Singleton;/*** 双重校验*      1、get方法里面判断两次是否为null;*      2、外层判断不空,就直接返回;*      3、外层判断空,就抢资源,抢到资源后还需要防止前面进去的线程已经创建了;*/
public class Singleton_04 {// 1.私有构造方法private Singleton_04() {}// 2.创建私有的静态的全局对象// volatile 这个关键字可以保证变量的可见性,屏蔽指令重排序private volatile static Singleton_04 instance;// 3.给外部提供全局访问点public static Singleton_04 getInstance() {if (null == instance)synchronized (Singleton_04.class){// 抢到锁之后,第二次判断// 进入同步代码块的线程需要防止之前进来的线程创建对象,所以需要再判断一次;if (null == instance)instance = new Singleton_04();}return instance;}
}

5、懒汉单例 - 静态内部类:代码简单

package creationPattern.Singleton;/*** 静态内部类* 1、利用静态内部类的特性:外部类使用到了内部类的属性或者方法时,才会加载内部类;* 2、实现延时加载、线程安全、代码简单* 3、静态内部类里面实际上也是一个饿汉加载,只是类不被加载,它没办法创建实例;*/
public class Singleton_05 {// 1.私有构造方法private Singleton_05() {if (null != SingletonHandler.instance) {throw new RuntimeException("非法访问构造方法");}}// 2.创建静态内部类private static class SingletonHandler {// 3.创建私有的静态的全局对象private static Singleton_05 instance = new Singleton_05();}// 4.提供外部方法public static Singleton_05 getInstance() {return SingletonHandler.instance;}
}

6、反射对单例的破坏

package creationPattern.Singleton;import java.lang.reflect.Constructor;/*** 反射对单例的破坏*/
public class Test_Reflect {public static void main(String[] args) {Class<Singleton_05> clazz = Singleton_05.class;try {// 获取私有构造方法Constructor<Singleton_05> constructor = clazz.getDeclaredConstructor();constructor.setAccessible(true);Singleton_05 singleton05 = constructor.newInstance();System.out.println(singleton05);} catch (Exception e) {throw new RuntimeException(e);}}
}

-- 加个判断解决

9、序列化对单例有破坏

10、系列化对单例有破坏

11、使用枚举实现的单例模式具有懒加载、线程安全、不被反射和序列化破坏的特点;


http://www.mrgr.cn/news/7241.html

相关文章:

  • 求数组中出现次数超过一半的数字
  • Nacos微服务注册管理中心与服务通信
  • 驱动 day1 --内核的编译
  • 玩客云刷机armbian后docker启动不起来,提示bpf_prog_query(BPF_CGROUP_DEVICE) failed
  • 深入理解HTML中的script defer属性
  • oracle 如果是多条插入语句用begin end 快还是一条一条插入快?
  • 大数据开发工程师面试整理-如何处理紧急的生产环境问题?
  • 卓越测试工程师必备:团队协作的艺术
  • “双指针”算法下篇
  • STM32 HAL SDADC DMA
  • Deepin【2】:Deepin系统盘扩容
  • 代码随想录算法训练营第57天|prim算法精讲、kruskal算法精讲
  • 动态规划--爬楼梯
  • Linux阿里云服务器,利用docker安装EMQX
  • SyntaxError: Unexpected token ‘??=‘ 解决办法
  • Nginx反向代理在Web应用中的实践
  • 高性能计算应用优化之运行参数优化
  • computer version 如何做背景建模中处理噪声和光照变化
  • Navicat中怎么查看数据库密码
  • Visual Studio中 自动生成版本号递增版本号