博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
GOF23设计模式之单例模式
阅读量:4537 次
发布时间:2019-06-08

本文共 4095 字,大约阅读时间需要 13 分钟。

GOF23设计模式(Group Of Four)

为国外很有名的四个大牛总结的23总常见的套路

分类:

1)创建型模式

、工厂模式、抽象工厂模式、建造者模式、原型模式

2)结构型模式

适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式

3)行为型模式

模板方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式

 

单例模式

核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点

单例模式的优点:

由于单例模式只生成一个实例,减少了系统性能开销。

单例模式可以在系统设置全局的访问点,优化共享资源访问。例如可以设计一个单例类,负责所有数据表的映射处理。

常见的五种单例模式的实现方式:

主要:

饿汉式(线程安全,调用效率高。但是,不能延时加载。)

package cn.taosir.design.create.singleton;/** * 饿汉式 * @author taosir * */public class HungryType {    //类初始化时立即加载(不具备延时加载的优势),由于加载类时天然是线程安全的    private static HungryType hungryType=new HungryType();        //构造方法私有化    private HungryType() {};        //开放方法供外部提取实例,方法不需要同步,调用效率高    public static HungryType getInstance() {        return hungryType;    }}

懒汉式(线程安全,调用效率不高。但是,可以延时加载。)

package cn.taosir.design.create.singleton;/** * 懒汉式 * @author taosir * */public class LazyType {        //类初始化时,不初始化这个对象(延时加载,真正需要的时候才创建实例)    private static LazyType lazyType;        //构造方法私有化    private LazyType() {};        //方法同步,调用效率低    public static synchronized LazyType getInstance() {        if(lazyType==null)            lazyType=new LazyType();        return lazyType;    }}

其他:

双重检测锁式(由于JVM底层内部模型原因,偶尔会出现问题,不建议使用)

静态内部类式(线程安全,调用效率高。但是,可以延时加载,结合了饿汉式和懒汉式的优点)

package cn.taosir.design.create.singleton;/** * 静态内部类实现 * @author taosir * */public class StaticInner {    //使用一个静态的内部类来创建实例,当使用下面的StaticInnerInstance.staticInner时才会初始化    private static class StaticInnerInstance{        private static final StaticInner staticInner=new StaticInner();    }        //方法没有同步,调用效率高    public static StaticInner getInstance() {        return StaticInnerInstance.staticInner;    }        //私有化构造方法    private StaticInner() {}}

枚举单例(线程安全、调用效率高,不能延时加载)

package cn.taosir.design.create.singleton;/** * 枚举单例 * @author taosir * */public enum Enumeration {    //这个枚举元素本身就是单例    INSTANCE;        //添加自己需要的操作    public void doYouWantToDo() {            }}

 使用反射和反序列化破解单利模式及如何防止破解

  破解单例模式的方法

package cn.taosir.design.create.singleton;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.lang.reflect.Constructor;/**  * * 测试反射和反序列化破解单利模式 * @author Administrator * */public class CrackDemo {    public static void main(String[] args) throws Exception {                        LazyType4Crack lazy=LazyType4Crack.getInstance();                //反射//        Class
clazz=(Class
)Class.forName("cn.taosir.design.create.singleton.LazyType4Crack");// Constructor
constructor=clazz.getDeclaredConstructor(null);// constructor.setAccessible(true);//此方法可以跳过权限的检查,破解单例// LazyType4Crack lazyOne=constructor.newInstance();// System.out.println(lazy);// System.out.println(lazyOne);// System.out.println(lazy==lazyOne); //序列化 FileOutputStream fos=new FileOutputStream("./a.txt"); ObjectOutputStream ooStream=new ObjectOutputStream(fos); ooStream.writeObject(lazy); ooStream.close(); fos.close(); //反序列化 ObjectInputStream ois=new ObjectInputStream(new FileInputStream("./a.txt")); LazyType4Crack layCrack=(LazyType4Crack)ois.readObject(); System.out.println(lazy==layCrack); }}

防止破解的方法(以懒汉式为例)

package cn.taosir.design.create.singleton;import java.io.Serializable;/** * * 懒汉式(如何防止反射和反序列化漏洞) * @author taosir * */public class LazyType4Crack implements Serializable{    //类初始化时,不初始化这个对象(延时加载,真正需要的时候才创建实例)    private static LazyType4Crack lazyType4Crack;    //构造方法私有化    private LazyType4Crack() {
     //防止反射 if(lazyType4Crack!=null) { throw new RuntimeException(); } } //方法同步,调用效率低 public static synchronized LazyType4Crack getInstance() { if(lazyType4Crack==null) lazyType4Crack=new LazyType4Crack(); return lazyType4Crack; } //反序列化时,如果定义了readResolve()则直接返回此方法指定的对象。而不需要单独再创建新对象 private Object readResolve() { return lazyType4Crack; }}

 

转载于:https://www.cnblogs.com/it-taosir/p/10017549.html

你可能感兴趣的文章
ArcGIS API for JavaScript 4.2学习笔记[14] 弹窗的位置、为弹窗添加元素
查看>>
电路基础
查看>>
jquery 对象与DOM对象转换
查看>>
DELPHI 调用系统 ADO 配置窗体 提高软件易用性
查看>>
Mongodb 命令及 PyMongo 库的使用
查看>>
div+css 兼容ie6 ie7 ie8 ie9和FireFox Chrome等浏览器方法(非原创)
查看>>
关于SDWebImage加载高清图片导致app崩溃的问题
查看>>
如何查看方法在哪里被调用
查看>>
HUE的自动化安装部署
查看>>
图片服务器(FastDFS)的搭建
查看>>
myBatis应用
查看>>
RuntimeError: DataLoader worker (pid 18255) is killed by signal: Killed.
查看>>
[PHP] 用AppServ一步到位安装PHP服务器
查看>>
mac brew install redis 报错
查看>>
Work? working!
查看>>
开源收藏
查看>>
profile default1
查看>>
Linux Too Many OpenFiles
查看>>
ural 1303 Minimal Coverage(贪心)
查看>>
学用MVC4做网站三:3.3更新栏目
查看>>