JAVA单例模式

单例模式

通过本文将学习到

  1. 设计模式是什么
  2. 设计模式关注那些点
  3. 单例模式的概念
  4. 单例模式的作用
  5. 懒汉模式与饿汉模式的异同
  6. 单例模式优缺点

 

1、前言

聊聊我为什么会学设计模式,在大三、大四的时候我完成了对JAVA基础以及JAVAEE的一些学习!也能够完成一些小网站的开发,但是我发现自己写的代码,冗余度非常高,可扩展性又非常低,所以我就在网上寻找如何可以提升自己代码的可扩展性的方法。经过我在百度、csdn、谷歌各种搜素后发现设计模式是能够提升自己这些能力的一个选择。因此最近我在研读这本书,想要把其中的大部分设计模式都理解分析。此文档是我的一些总结收获!

 2、设计模式的概念

设计模式,其实是起源于建筑学!它是对前人经验的总结,为后人设计与开发基于面向对象软件的提供指导方针以及成熟的解决方案!

谈到设计模式不得不说模式。模式:模式是在特定环境下人们解决某类重复出现问题的一套成功或者有效的方案。做很多事情都是有模式的,或者你可以说成一种套路,一种解决方案都行!设计模式是针对与软件模式中类,对象之间的相互作的一套解决方案!

设计模式的作用:使用设计模式是为了可重用代码、让代码更容易被他人理解并且提高代码的可靠性。

设计模式的分类:一般来说设计模式分为两种。1、根据目的分类。2、根据范围分类。我们先从范围分类说起,因为比较简单。

设计模式的范围是根据它是处理类之间的关系还是对象之间的关系而划分的。

(1)、范围分类

1.类模式:处理的是类和子类的关系,这些关系即是继承关系。在编译的候就被确定下来,是一种静态的关系。

2.对象模式:处理对象间的关系,这些关系在运行时变化,有动态性。

(2)根据目的来分。

根据目的来分大致分为三类1、创建型;2、结构型;3、行为型;

1.创建型:顾名思义,创建型的就是创建对象的!没对象的请注意可以通过创建模式来new一个对象。妈妈再也不用担心喂狗粮了!GoF小组提出的23中设计模式中就有5种是创建对象的。分别是。工厂方法模式(Factory Method)、抽象工厂模式(Abstract Method)、建造者模式(Builder)、原型模式(Prototype)和单例模式(Singleton)。

2.结构型模式:这个模式主要用于处理类或对象的组合,Gof提出了七种结构性的适配器模式(Adapter)、桥接模式(Bridge)、组合模式(Composite)、装饰模式(Decorator)、外观模式(Façade)、享元模式(Flywight)和代理模式(Proxy)。

3. 行为型模式:其主要的作用就是规定类和对象怎么样交互以及如何分配职责,责任链模式(Chain of Responsibility)、命令模式(Command)、迭代器模式(Iterator)、中介者模式(Mediator)、备忘录模式(Memento)、观察者模式(Observer)、访问者模式(Visitor)、策略模式(Strategy)、状态模式(State)、模板方法模式(Template Method)。

3、设计模式需要关注的点

         设计模式需要关注的点,即是其构成的基本要素!但是,我们只要关心其中的某些信息便已经足够了。

         设计模式的基本要素一般包含模式名称、问题、目的、解决方案、效果、实例代码和相关设计模式。我们只需要关注:设计模式的名称、问题、解决方案、效果即可。

         名称:设计模式的名称如(单例模式)。在设计的时候,以及软件种命名的时候一定要以相对应得英文来命名,方便记忆同时更加容易阅读,如(xxxxFactory)(xxxxAdapter)。

         问题:问题是在软件设计中出现的问题,在什么问题中使用对应的设计模式这是一个关键的信息。或者说在什么条件下适用这以设计模式!

         解决方案:描述得是设计模式得组成成分,以及这些成分之间的关系。各自的职责。模式是一个通用的模板,他不是具体得实现。而是提供设计问题的抽象描述和怎样用一个具体的一般意义的元素组合来解决的。所以用类图来说明,我们所要干的就是记住类图,和核心代码。

         效果:一个设计模式可能会帮你解决一些问题,但同时也可能会产生新的问题。所以需要通过自身的软件进行评判是否使用该设计模式 。

         接下来的分析,就是通过 设计模式的名称、问题、解决方案、效果来说明!

4、单例模式的概念及作用

单例模式:确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例。

问题:为什么要有单例模式了,虽说它是最简单的设计模式,但是其实它的作用却也非常大。列如,一个系统只有系统管理器,或者说一个系统只有一个计时器。如果你不用一个方法将这一个对象唯一化,那势必会出现很多个窗口,或者很多个计时器。如果他们的内容完全一样,那就是浪费系统资源。如果不一样那就会产生很多状态,那怎么判断哪个状态是对的了?如何保证对象唯一了?一个办法就是自身创建并且保存自己的唯一实例。这就是单例模式的动机。

解决方案:

单例模式是创造型的模式关键三个点:1 某个类只能有一个实例;2它必须自己创建这个实例;3 它必须自己向整个系统提供这个实例。

UML:

在整个单例模式中就只有一个角色,那就是类本身。没很多复杂的逻辑。

DEMO:

public class Singleton {

    //自己创建自己的对象,注意是私有的,且是静态的,因为要让所有的类都能调用。

    private static Singleton instance = null;

    //私有化构造函数,让除了自己谁都不能调用。

    private Singleton(){}

    //第三步,提供一个可供全局访问的静态类。

    public static Singleton getSingleton(){

                  //判断instance是否已经被创建,没有则创建。

           if(instance == null)

           instance = new Singleton();

           return instance;

    }

 

}

写完这个类可以通过创建两个单例对象来比较一下 。

 

 

5、饿汉模式

   饿汉模式单例类是实现起来最简单的单例类,是单例模式的一个变种,它的uml图结构如下。

   UML:

简单的来说就是它将NEW自己的那个步骤直接放在了创建自己的私有对象的时候。

DEMO:
 

public class EagerSingleton {

        //创建私有化的属性的同时将自己给自己新建了,静态的常量的

        private static final EagerSingleton instance = new EagerSingleton();

        //构造函数私有化掉

        private EagerSingleton() {};

        //给提供全局的方法。

        public static EagerSingleton getEagerSingleton() {

            return instance;

        }

}

 

 

6、懒汉模式

懒汉模式单例类是我个人觉得相对来说比较麻烦的一件事情了。其麻烦的关键点在于,它和其他的单例模式不同,其他模式在加载的时候就被实例了,而懒汉模式却需要等第一次引用的时候才被加载。饿汉模式优点在于无需考虑多个线程同时访问的问题,因为就一个实例。同时从调用速度和反应时间来看,由于饿汉模式在程序一开始就被加载了所以要优于懒汉模式。但是,如果从系统来讲,饿汉模式无论是否要被使用到都要被创建所以从系统资源来说饿汉模式不及懒汉模式。并且在系统加载的时候要创建饿汉模式的实例所以可能会等待。

         懒汉模式实现的是延迟加载,在第一次被使用的时候被创建。无需一直占用资源。但是有个比较蛋疼的问题,你得处理当多个线程访问的时候的问题,必须给它上锁。

UML图:

        

DEMO:

 

public class LazySingleton {

       

    //私有化单例对象

    private static LazySingleton instance = null;

    //创建私有的构造函数

    private LazySingleton() {};

    //通过synchronized关键字对方法进行加锁,确保任意时刻只有一个线程在使用这个方法。

    synchronized public static LazySingleton getInstance() {

        if(instance==null) {

            instance = new LazySingleton();

        }

        return instance;

    }

}

 

 

7、总结

         单例模式是一个创建型的设计模式。其优点/缺点与适合的环境分别是:

优点:

  1. 单例模式提供了对唯一实力的受控制访问。因为它自己封装了它的唯一实例,所以它可以严格的控制客户端怎么样去访问它。
  2. 由于在系统中就一个对象,可以节省系统资源。对于一些需要频繁创建的对象单例模式无疑可以提高很多的性能。

  缺点:

  1. 由于单例模式没有抽象层,所以难以扩展。
  2. 由于单例模式职责太多,又要创建,又要提供访问,过于耦合,违背了单一原则。

使用的环境:

  1. 系统只需要一个实例对象。
  2. 客户调用的实例只允许一个公共访问点。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值