单例模式 -- Singleton

2017-03-21 13:48:09   最后更新: 2017-03-21 13:48:09   访问数量:194




单例模式是最简单的创建型模式,他保证了一个类仅有一个实例,并且提供访问这个实例的全局访问方式

很多情况下,保证一个类同时最多只有一个实例是非常必要的,例如项目中的线程池组件,之所以使用线程池,往往是为了降低反复创建、销毁线程的开销,如果项目中维护多个线程池将是很令人头疼的一件事

有时,一个类也并没有必要存在多个实例,例如对于线程安全的类来说,一个实例可以处理并发环境下的所有请求,如果为每一个请求单独创建一个类实例,那么会造成很大程度上的资源浪费

 

 

 

如图所示,sigleton 模式的构成非常简单,只需要单例类提供一个 instance 操作,用来创建一个全局唯一类实例或返回一个已创建的类实例

 

单例模式拥有很多优点:

  1. 对唯一实例的受控访问 -- 因为单例模式封装了他的唯一实例,所以他可以对这个仅有的实例进行严格的访问控制
  2. 缩小命名空间 -- singleton 模式中,类实例虽然是全局唯一的,但是类实例的获取却是通过 Singleton 类局部获取的,这样就避免了将唯一实例作为全局变量存储时发生的命名空间污染问题
  3. 允许可变数目的类实例 -- 如果需要一定数目的多个实例,Singleton 也可以维护并控制他们的访问
  4. 资源利用率提升 -- 正如前面提到的,这个优点是显而易见的

 

对于我们的 MazeGame 来说,如果要求每次最多只能创建一个游戏实例,使用单例是十分必要的

 

MazeFactoryEnum

package com.techlog.designpattern.mazegame.model; import com.techlog.designpattern.mazegame.service.BoomMazeFactory; import com.techlog.designpattern.mazegame.service.StandardMazeFactory; /** * Created by techlog on 2017/3/21. */ public enum MazeFactoryEnum { BOOM_MAZE_FACTORY(BoomMazeFactory.class), STANDARD_MAZE_FACTORY(StandardMazeFactory.class), ; private Class<?> mazeFactoryClass; MazeFactoryEnum(Class<?> mazeFactoryClass) { this.mazeFactoryClass = mazeFactoryClass; } public Class<?> getMazeFactoryClass() { return mazeFactoryClass; } public void setMazeFactoryClass(Class<?> mazeFactoryClass) { this.mazeFactoryClass = mazeFactoryClass; } }

 

 

MazeFactory

package com.techlog.designpattern.mazegame.service; import com.techlog.designpattern.mazegame.model.MazeFactoryEnum; /** * Created by techlog on 2017/3/21. */ public class MazeFactory { public static synchronized MazeFactory instance(MazeFactoryEnum mazeFactoryEnum) { try { Class<?> mazeFactoryClass = mazeFactoryEnum.getMazeFactoryClass(); if (__instance == null) { __instance = (MazeFactory) mazeFactoryClass.newInstance(); } return __instance.getClass() == mazeFactoryClass ? __instance : null; } catch (Exception e) { return null; } } private static MazeFactory __instance; }

 

 

说明

我们首先创建了一个 MazeFactoryEnum 用来保存 MazeFactory 的所有子类,这样我们就可以通过用它作为参数来判断具体该实例化哪个子类了

在接下来的 MazeFactory 中,我们创建了 instance 方法,用来创建或获取全局唯一的工厂实例

至于为什么要加 synchronized 锁,以及这样做是否存在问题或者是否存在进一步的优化空间,以及 mazeFactoryClass.newInstance() 与 new 对象有什么区别,创建对象的几种方式,这些 java 相关的问题,我们会在接下来的其他文章中介绍,敬请期待

 






技术帖      龙潭书斋      java      单例模式      singleton      设计模式      模式      创建型模式      design pattern      单例      instance     


京ICP备15018585号