首页 > 其他分享 >《设计模式之禅》Singleton_Pattern--单例模式

《设计模式之禅》Singleton_Pattern--单例模式

时间:2023-05-24 21:31:48浏览次数:55  
标签:Singleton Emperor singletonPattern 之禅 皇帝 单例 设计模式 public SingletonPattern

单例模式

这个模式是很有意思,确实很有意思的,而且比较简单,但是我还是要说因为它使用的是如此的广泛,如此的有人缘,单例就是单一、独苗的意思,那什么是独一份呢?你的思维是独一份,除此之外还有什么不能山寨的呢?我们举个比较难复制的对象:皇帝(就是那个天子)

中国的历史上很少出现两个皇帝并存的时期,是有,但不多(可以想象瓦剌战神),那我们就认为皇帝是个单例模式,在这个场景中,有皇帝,有大臣,大臣是天天要上朝参见皇帝的,今天参拜的皇帝应该和昨天、前天的一样(过渡期的不考虑,别找茬哦),大臣磕完头,抬头一看,嗨,还是昨天那个皇帝,单例模式,绝对的单例模式,先看类图:

《设计模式之禅》Singleton_Pattern--单例模式_构造函数

程序实现

定义一个皇帝

/**
 * @author LeeZhi
 * @version 1.0
 */
@SuppressWarnings({"all"})
public class Emperor {
    private static Emperor emperor = null; //定义一个皇帝放在那里,然后给这个皇帝名字

    public Emperor() {
        //世俗与道德约束,不会产生第二个皇帝{
    }

    public static Emperor getInstance(){
        if (emperor==null){
            //如果皇帝还定义,那就定义一个皇帝
            emperor = new Emperor();
            System.out.println(emperor);
        }
        return emperor;
    }
    public static void emperorInfo(){
        System.out.println("天大地大,皇权天赋,老子是天子,我最大,我就是皇帝XXX");
    }
}

通过无参构造器限制一下

定义静态方法,getInstance获取一个皇帝的实例化对象。

定义大臣

/**
 * @author LeeZhi
 * @version 1.0
 */
@SuppressWarnings({"all"})
public class Minister {
    public static void main(String[] args) {

        //第一天
        Emperor emperor1 = Emperor.getInstance();
        emperor1.emperorInfo();

        //第二天
        Emperor emperor2 = Emperor.getInstance();
        emperor2.emperorInfo();

        //第三天
        Emperor emperor3 = Emperor.getInstance();
        emperor3.emperorInfo();
        //三天见的皇帝都是同一个人,荣幸吧!

    }
}

看到没,大臣天天见到的都是同一个皇帝,不会产生错乱情况,反正都是一个皇帝,是好是坏就这一个(管他昏君明君),只要提到皇帝,大家都知道指的是谁,清晰,而又明确。问题是这是通常情况,还有个例的,如同一个时期同一个朝代有两个皇帝,怎么办?瓦剌战神又来了

Attation

单例模式很简单,就是在构造函数中多了加一个构造函数,访问权限是private的就可以了,这个模式是简单,但是简单中透着风险,风险?什么风险?在一个B/S项目中,每个HTTP Request请求到J2EE的容器上后都创建了一个线程,每个线程都要创建同一个单例对象,怎么办?,好,我们写一个通用的单例程序,然后分析一下:

/**
 * @author LeeZhi
 * @version 1.0
 * 通用单例模式
 */
@SuppressWarnings("all")
public class SingletonPattern {
    private static SingletonPattern singletonPattern = null;

    //通过无参构造器限制不能直接产生一个实例


    private SingletonPattern() {
    }

    public SingletonPattern getInstance(){
        if(this.singletonPattern==null){ //如果还没有实例,就创建一个
            this.singletonPattern = new SingletonPattern();
        }
        return this.singletonPattern;
    }
}

《设计模式之禅》Singleton_Pattern--单例模式_单例模式_02

我们来看黄色的那一部分,假如现在有两个线程A和线程B,线程A执行到this.singletonPattern=new SingletonPattern (正在申请内存分配,可能需要0.001微秒,就在这0.001微秒之内,线程B执行到if(this.singletonPattern=null),你说这个时候这个判断条件是true还是false?是true,那然后呢?线程B也往下走,于是乎就在内存中就有两个SingletonPattern的实例了,看看是不是出问题了?如果你这个单例是去拿一个序列号或者创建一个信号资源的时候,会怎么样?业务逻辑混乱!数据一致性校验失败!最重要的是你从代码上还看不出什么问题,这才是最要命的!因为这种情况基本上你是重现不了的,不寒而栗吧,那怎么修改?有很多种方案,我就说一种,能简单的、彻底解决问题的方案:

修改后

/**
 * @author LeeZhi
 * @version 1.0
 * 通用单例模式
 */
@SuppressWarnings("all")
public class SingletonPattern {
    private static SingletonPattern singletonPattern = new SingletonPattern();

    //通过无参构造器限制不能直接产生一个实例
    private SingletonPattern() {
    }

//    public SingletonPattern getInstance(){
//        if(this.singletonPattern==null){ //如果还没有实例,就创建一个
//            this.singletonPattern = new SingletonPattern();
//        }
//        return this.singletonPattern;
//    }
        public synchronized SingletonPattern getInstance(){
            return singletonPattern;
    }
}

直接new一个对象传递给类的成员变量singletonpattern,你要的时候getInstance()直接返回给你,解决问题!

说白了,就是在进程(或者线程)里只能有一个实例化的对象,记得无参构造器要给私有权限。

标签:Singleton,Emperor,singletonPattern,之禅,皇帝,单例,设计模式,public,SingletonPattern
From: https://blog.51cto.com/u_15915681/6342997

相关文章

  • 设计模式(一)创建型
    1、单例模式饿汉模式(最简单):类加载的时候就创建对象,线程安全publicclassSingleton{//首先,将构造方法私有化privateSingleton(){};//创建私有静态实例,意味着在类加载就会进行创建privatestaticSingletoninstance=newSingleton();public......
  • 设计模式
     模板方法设计模式非常重要 什么场景使用过  聚合支付  有共同行为的场景 聚合支付:银联支付支付宝支付 微信支付通过回调通知支付成功修改订单状态为成功1、暴露一个接口,提供给第三方支付回调2、多家支付回调通知参数报文都不相同,但是有共同的通知行为。......
  • 二十三天搞懂设计模式之抽象工厂模式
    文章目录抽象工厂模式1.介绍2.实现3.代码4.总结抽象工厂模式1.介绍意图:提供一个创建一系列相关或者依赖的接口,而无需指定他们具体的类何时使用:系统的产品有多于一个产品族,而系统只消费其中某一族的产品,例子如下当前有个换装游戏,进入不同的游戏场景需要选择不同的游戏套装,比......
  • 二十三天搞懂设计模式之工厂模式
    文章目录1.定义2.工厂模式2.1实现2.2第一种方式代码3.总结1.定义在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。单例也是一种工厂为什么有了new之后,还要有工厂灵活控制生产过程权限、修饰、日志2.工厂模式2.......
  • C#设计模式——上
    文章目录设计模式序言-四大发明之活字印刷——面向对象思想的胜利四大发明之活字印刷——面向对象思想的胜利第一章面试受挫——代码无错就是好?第二章代码规范、重构第三章复制VS复用第四章业务的封装第五章体会简单工厂模式的美妙设计模式序言-四大发明之活字印刷——面向......
  • Java设计模式-原型模式
    简介原型模式是一种创建型设计模式,它允许在运行时通过复制现有对象来创建新对象,而不是通过构造函数创建。这个模式的核心思想是基于一个现有的对象克隆一个新的对象,这个过程对外部世界是透明的,就像对象从未被克隆过一样。原型模式的一个关键优点是可以避免在创建对象时重复性地......
  • C# 常用设计模式有哪些
    原文地址:C#常用设计模式有哪些-C#入门教程-.NET果糖网(donet5.com)C#中常用的设计模式有很多,以下列举几个常用的:1.工厂模式(FactoryPattern)通过工厂方法创建对象,隐藏对象的实例化过程,提供灵活性和可扩展性。1publicinterfaceIAnimal2{3voidSpeak();4......
  • JAVA设计模式之责任链模式
    文章目录一、责任链(ChainofResponsibility)模式二、责任链模式的结构三、源码四、纯的与不纯的责任链模式五、总结一、责任链(ChainofResponsibility)模式顾名思义,责任链模式(ChainofResponsibilityPattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发......
  • python之禅 代码规范
    触发方法:在python解释器中输入importthis Python之禅byTimPeters() 优美胜于丑陋(Python以编写优美的代码为目标)明了胜于晦涩(优美的代码应当是明了的,命名规范,风格相似)简洁胜于复杂(优美的代码应当是简洁的,不要有复杂的内部实现)复杂胜于凌乱(如果复杂不可避免,那代码间......
  • Java设计模式-组合模式
    简介在软件设计中,设计模式是一种被广泛接受和应用的经验总结,旨在解决常见问题并提供可复用的解决方案。组合模式是一种结构型设计模式,它允许将对象组合成树形结构以表示“部分-整体”的层次结构。这种模式能够使客户端以一致的方式处理单个对象和对象集合,将对象的组合与对象的使......