Skip to content

Latest commit

 

History

History
195 lines (162 loc) · 8.38 KB

File metadata and controls

195 lines (162 loc) · 8.38 KB

设计模式相关

目录


1. 编写线程安全的单例模式。
2. 享元模式
3. 原型模式
4. 详细的设计模式内容

  • 1.编写线程安全的单例模式。

实现方式一:
     利用静态内部类实现单例模式(极力推荐)

public class Singleton{ //“延迟加载”,“线程安全”
    
    private Singleton(){}
    
    private static class T{ //静态内部类在使用的时候才加载,且只加载一次
        private static Singleton t=new Singleton();
    }
    
    public static Singleton getInstance(){
        return T.t;
    }
    
}
  • 实现方式二:
         双重校验锁 DCL(double checked locking)--使用 volatile 的场景之一

    public class Singleton { //注意需要用 volatile 关键字 private static volatile Singleton instance = null; private Singleton() {} //双重检查加锁,只有在第一次实例化时,才启用同步机制,提高了性能。 public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton();// 注意这条语句,非原子操作 } } } } return instance; }
    }

     现在想象一下有线程 A 和 B 在调用 getInstance(),线程 A 先进入,在 执行到 instance=new Singleton():的时候被踢出了 cpu。然后线程 B 进入,B 看到的是 instance 已经不是 null 了(内存已经分配),于是它开始放心地使用 instance,但这个是错误的,因为 A 还没有来得及完成 instance 的初始化,而线 程 B 就返回了未被初始化的 instance 实例(为了禁止指令重排序,就用 volatile 关键字)。
     看似简单的一段赋值语句:instance= new Singleton(),但是很不幸它并不是一个原 子操作,其实际上可以抽象为下面几条 JVM 指令:
memory =allocate();//1:分配对象的内存空间
ctorInstance(memory); //2:初始化对象
instance =memory;//3:设置 instance 指向刚分配的内存地址
     上面操作 2 依赖于操作 1,但是操作 3 并不依赖于操作 2,所以 JVM 是可以针对它们 进行指令的优化重排序的,经过重排序后如下:
memory =allocate();//1:分配对象的内存空间
instance =memory;//3:instance 指向刚分配的内存地址,此时对象还未初始化
ctorInstance(memory); //2:初始化对象
     可以看到指令重排之后,instance 指向分配好的内存放在了前面,而这段内存的初始 化被排在了后面。
     在线程 A 执行这段赋值语句,在初始化分配对象之前就已经将其赋值给 instance 引用, 恰好另一个线程进入方法判断 instance 引用不为 null,然后就将其返回使用,导致出错。

  • 实现方式三:

    public class SafeLazyInitialization { private static Resource resource; } public synchronized static Resource getInstance() { if (resource == null) resource = new Resource(); return resource; }

单例模式应用场景:
     数据库连接池,多线程的线程池。 Windows 的任务管理器就是很典型的单 例模式。

String 采用了享元设计模式(flyweight)

     原型模式主要用于对象的复制,实现一个接口(实现 Cloneable 接口), 重写一个方法(重写 Object 类中的 clone 方法),即完成了原型模式。
     原型模式中的拷贝分为"浅拷贝"和"深拷贝":
     浅拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量只复制 引用,不复制引用的对象.
     深拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量也进行 引用对象的复制.
(Object 类的 clone 方法只会拷贝对象中的基本数据类型的值,对于数组、 容器对象、引用对象等都不会拷贝,这就是浅拷贝。如果要实现深拷贝,必须 将原型模式中的数组、容器对象、引用对象等另行拷贝。)
     原型模式的优点
     1.如果创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程。
     2.使用原型模式创建对象比直接 new 一个对象在性能上要好的多,因为 Object 类的 clone 方法是一个本地方法,它直接操作内存中的二进制流,特别 是复制大对象时,性能的差别非常明显。
     原型模式的使用场景。
     因为以上优点,所以在需要重复地创建相似对象时可以考虑使用原型模式。 比如需要在一个循环体内创建对象,假如对象创建过程比较复杂或者循环次数 很多的话,使用原型模式不但可以简化创建过程,而且可以使系统的整体性能 提高很多。

迭代器及迭代器模式
工厂、适配器、责任链、观察者
手写一个工厂模式。
外观模式。
命令模式
组合模式
     常见设计模式,如 singlen, factory, abstract factory, strategy, chain, adaptor, decorator, composite,template,absever 等。
工厂方法模式的优点(低耦合、高内聚,开放封闭原则)

1.观察者设计模式
     观察者模式定义了对象间的一对多依赖关系,让一个或多个观察者对象观察一个 主题对象。当主题对象的状态发生变化时,系统能通知所有的依赖于此对象的观察者 对象,从而使得观察者对象能够自动更新。
     在观察者模式中,被观察的对象常常也被称为目标或主题(Subject),依赖的 对象被称为观察者(Observer)

2.装饰者设计模式
     现在需要一个汉堡,主体是鸡腿堡,可以选择添加生菜、酱、辣椒等等许多其他的 配料,这种情况下就可以使用装饰者模式。

3.工厂设计模式
     4.1 简单工厂模式
简单工厂模式的实质是由一个工厂类根据传入的参数, 动态决定应该创建出哪一 个产品类的实例。
     4.2 抽象工厂模式
在这个模式中的几类角色, 有抽象工厂, 实体工厂, 抽象产品, 实体产品。
http://www.cnblogs.com/suizhouqiwei/archive/2012/06/26/2563332.html
     4.3 工厂方法模式

24种设计模式介绍与6大设计原则.pdf

Java 中一般认为有23 种设计模式,我们不需要所有的都会,但是其中常用的几种设计模式应该去掌握。
下面列出了所有的设计模式。需要掌握的设计模式我单独列出来了,当然能掌握的越多越好。
总体来说设计模式分为三大类:
创建型模式,共五种:
工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:
适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:
策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。


搬运工信息