23种设计模式总结与分析override1

  • 1 单例模式
    • 1.1 饿汉式
    • 1.2 静态方法
    • 1.3 懒汉式
    • 1.4 懒汉式加锁
    • 1.5 给类加锁(错误方法)
    • 1.6 双重检查
    • 1.7 静态内部类方法(完美)
    • 1.8 枚举类
  • 2 Factory(工厂)模式
    • 抽象工厂
  • 3 Strategy(策略)模式(接口与实现)
  • 4 Facade 门面(外观)模式
  • 5 Mediator(中介/调停者)模式
  • 6 Decorator(装饰)模式

1 单例模式

有些时候,我们只需要新建实例,该实例通过继承与多态创建各种不一样的场景实例对象,该类提供了一种访问其唯一的实例对象的方式,可以直接访问,不需要实例化该类的对象,这样也可以保证JVM线程安全。单例模式属于创建型模式,它提供了一种创建对象的最佳方式在Spring的Bean工厂和Manager中,单例模式就得到了广泛使用

1.1 饿汉式

饿汉式是单例模式中最简单也是最实用的方法,故名起义,该方法就像一个饿汉一样,只要有食物(新的类加载至内存),饿汉就要吃进去(实例化),宝成了1

/*** 饿汉式* 类加载到内存后,就实例化一个单例,JVM保证线程安全* 简单实用,推荐使用!* 唯一缺点:不管用到与否,类装载时就完成实例化* Class.forName("")* (话说你不用的,你装载它干啥)*/
public class Mgr01 {private static final Mgr01 INSTANCE = new Mgr01();private Mgr01() {};public static Mgr01 getInstance() {return INSTANCE;}public void m() {System.out.println("m");}// 通过主方法验证是不是只实例化了一个对象public static void main(String[] args) {Mgr01 m1 = Mgr01.getInstance();Mgr01 m2 = Mgr01.getInstance();System.out.println(m1 == m2);}
}


两个实例对象相等,是一个相同的实例。

1.2 静态方法

public class SingletonModule02 {private static final SingletonModule02 INSTANCE;static {INSTANCE = new SingletonModule02();}private SingletonModule02(){};public static SingletonModule02 getInstance(){return INSTANCE;}public void m(){System.out.println("m");}public static void main(String[] args) {SingletonModule02 m1 = SingletonModule02.getInstance();SingletonModule02 m2 = SingletonModule02.getInstance();System.out.println(m1 == m2);}
}

和饿汉式一样, 只是实例值的初始化变成了静态代码块

1.3 懒汉式

懒汉式就是此方法并不主动初始化实例对象,同时将构造方法设置为private,只有当前类可以访问,只有当调用获取实例的方法判断实例对象为空时,才初始化该实例对象。但是,此方法在多线程的时候会出现较大问题,有多个线程执行时,会一起判断实例是否为空,这时就会新建出不同的实例,一下代码可以验证

public class SingletonModule03 {private static SingletonModule03 INSTANCE;private SingletonModule03(){};public static SingletonModule03 getInstance() throws InterruptedException {if (INSTANCE == null){Thread.sleep(1);INSTANCE = new SingletonModule03();}return INSTANCE;}public void m(){System.out.println("m");}public static void main(String[] args) {for (int i = 0; i < 100; i++){new Thread(() ->{try {//获取当前实例的哈希码,不一样的实例哈希码不同System.out.println(SingletonModule03.getInstance().hashCode());} catch (InterruptedException e) {e.printStackTrace();}}).start();}}
}


可以看到实例的哈希码并不同,不是一个实例,所以懒汉式在多个线程运行实例时是有缺陷的

1.4 懒汉式加锁

应对上面的多线程初始化实例问题,最容易想到的方法就是加锁

public class Mgr04 {private static Mgr04 INSTANCE;private Mgr04() {}public static synchronized Mgr04 getInstance() {if (INSTANCE == null) {try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}INSTANCE = new Mgr04();}return INSTANCE;}public void m() {System.out.println("m");}public static void main(String[] args) {for(int i=0; i<100; i++) {new Thread(()->{System.out.println(Mgr04.getInstance().hashCode());}).start();}}
}

通过给getInstance方法加锁,达到线程安全的目的,但上锁会带来线程阻塞,导致程序运行效率下降

1.5 给类加锁(错误方法)

public class Mgr05 {private static Mgr05 INSTANCE;private Mgr05() {}public static Mgr05 getInstance() {if (INSTANCE == null) {//妄图通过减小同步代码块的方式提高效率,然后不可行synchronized (Mgr05.class) {try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}INSTANCE = new Mgr05();}}return INSTANCE;}public void m() {System.out.println("m");}public static void main(String[] args) {for(int i=0; i<100; i++) {new Thread(()->{System.out.println(Mgr05.getInstance().hashCode());}).start();}}
}

在判空方法里 只有当没有实例对象时,给该类加锁

但是测试发现,创建的都不是同一个实例对象。这是为何??? 主要原因还是在判断实例为空后,后面的操作都不是原子操作,有可能不同的线程拿到不同的锁创建不同的实例对象

1.6 双重检查

针对上述问题,又对程序进行改进,加入双重检测机制

public class Mgr06 {private static volatile Mgr06 INSTANCE; //JITprivate Mgr06() {}public static Mgr06 getInstance() {if (INSTANCE == null) {//双重检查synchronized (Mgr06.class) {if(INSTANCE == null) {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}INSTANCE = new Mgr06();}}}return INSTANCE;}public void m() {System.out.println("m");}public static void main(String[] args) {for(int i=0; i<100; i++) {new Thread(()->{System.out.println(Mgr06.getInstance().hashCode());}).start();}}
}

在给类上锁后,再进行一次判空操作,避免创建新的实例对象

1.7 静态内部类方法(完美)

比饿汉式还要完美、精辟的代码

我们的23种设计模式(一)相关推荐

  1. Java开发中的23种设计模式详解(转)

    设计模式(Design Patterns) --可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  2. 23 种设计模式实战 pdf(很全)

    今天分享一份学习资料:23 种设计模式实战教程.pdf,助你快速上手设计模式,写出各种高端代码,文末附下载地址. 设计模式一般分为三大类: 实战教程: 教程共 96 页PDF,太全了!纯粉丝福利,非广 ...

  3. 从追MM谈23种设计模式

    从追MM谈Java的23种设计模式 1.FACTORY-追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说&quo ...

  4. 【设计模式】Java 23种设计模式对比总结

    一.设计模式的分类 创建型模式,共五种(1-5):工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种(6-12):适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组 ...

  5. java 的23种设计模式 单例模式

    23种设计模式友情链接: 点击打开链接 单例模式: A.饿汉式单例模式 具体步骤: 1.声明一个私有的静态的最终的本类类型的对象并实例化 private static final Person ins ...

  6. 23种设计模式C++实现UML+源码汇总

    设计模式-汇总 代码开源仓库地址 23种设计模式C++实现 C++中的开闭原则使用C++多态功能实现附源码 C++基于多态实现依赖颠倒原则附源码 C++ 的静态成员变量为什么一定要在类外定义 23种设 ...

  7. 23种设计模式C++源码与UML实现--外观模式

    外观模式 facade模式也叫外观模式,是由GoF提出的23种设计模式中的一种,facade模式为一组具有类似功能的类群,比如类库,子系统等等,提供一个一致的简单界面.这个一致的简单的界面被称为fac ...

  8. 23种设计模式C++源码与UML实现--建造者模式

    建造者模式 代码仓库地址:建造者模式 Builder模式也叫建造者模式或者生成器模式,是由GoF提出的23种设计模式中的一种.Builder模式是一种对象创建模式之一,用来隐藏复合对象的创建过程.他把 ...

  9. 【java】java开发中的23种设计模式详解

    设计模式(Design Patterns) --可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  10. java 23种设计模式及具体例子 收藏有时间慢慢看

    设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代 码可靠性. 毫无疑问,设计模式 ...

最新文章

  1. SQL Server 2008_企业版和开发版产品密钥
  2. 鸿蒙申请敏感应用怎么选择,申请鸿蒙系统有一个应用选择怎么选择呢
  3. 五一假期将至,机房维护工作要做好
  4. 他手边有太多事要做了
  5. 查看是否由两个单词组成
  6. C++虚继承(五) --- 虚拟继承的概念
  7. C语言STATIC用法
  8. Mybatis-实现逆向代理
  9. AndroidStudio:Path is not a readable directory.
  10. ckpt下载 deeplabv3_Ubantu下 用deeplabV3+训练自己的数据集 你可能遇到的所有坑都在这了...
  11. WPS显示无法创建对象,请确认对象已在系统注册表中注册
  12. VB2010实例(1)_字符大小写转换
  13. 题解 SP4487 【GSS6 - Can you answer these queries VI】
  14. 浅析json_encode
  15. ssms远程服务器地址,SSMS无法连接到远程服务器,崩溃
  16. Unity_播放音乐
  17. 花了1晚上diy的matlab解数独算法,很好理解!
  18. 天耀18期 -09.数组【作业】.
  19. 专题论坛:云计算安全论坛
  20. 软件开发一般学什么?

热门文章

  1. Linux-less
  2. 日常sql总结(此贴持续更新)
  3. 九龙证券|主力资金 矿业龙头尾盘净买超亿元
  4. 密码正确登入不了网络计算机,电脑突然断网,然后重启输入密码就登陆不了电脑为什么?老是显示当前电脑时间与网络时间不一致...
  5. 如何让arduino中的loop和Processing中的draw停下来
  6. java前端显示统计报表数据_强大的报表前端展现功能
  7. SGU 187.Twist and whirl - want to cheat( splay )
  8. IntelliJ IDEA LicenseServer激活及使用
  9. MMrotate自定义数据集训练与验证格式转换脚本
  10. HD1201 18岁生日