个人觉得 纯粹的学习设计模式,是不对的。也不能为了使用设计模式,而硬搬设计模式来使用

  单例模式可能是 最简单的设计模式也是 大家知道最多的设计模式。当然 ,有很多种写法

  定义:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

  

  业务场景

  很多时候,我们的系统需要 很多的一些常量数据,这些数据在不同的环境下可能会不同。但是一旦确定了运行环境,这些配置常量,就不会改变。

  我们在代码中需要用到这些常量,如果每一次使用,都从配置文件中读取,这样会损耗大量的IO。所以将这些配置文件以单例的形式保存在内存中是一种完美的解决方案。

  饿汉式单例

public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return singleton;
}
}

  

  懒汉式单例

public class Singleton {
private static Singleton singleton;
private Singleton(){} public static synchronized Singleton getInstance(){
if(singleton==null){
singleton = new Singleton();
}
return singleton;
}
}

  

  本人最喜欢的一种模式,完美实现的实现既线程安全又延迟加载的模式(Initialization on demand holder)使用静态内部类

  lz认为这是大师级别的单例模式,只有对于类加载,初始化有清晰的了解才能写出这样的代码

public class ConfigSingleton { 

	//单例对象的属性( 私有化  对修改关闭,只从配置文件中读取)
private String ENVIRONMENT;
private String DOMAIN;
private String VERSION;
//get方法(对获取打开)
public String getENVIRONMENT() {
return ENVIRONMENT;
}
public String getDOMAIN() {
return DOMAIN;
}
public String getVERSION() {
return VERSION;
}
//私有化构造方法(禁止私自产生对象)
private ConfigSingleton (){
System.out.println("init configsingleton only once");
Properties pps = new Properties();
try {
InputStream in = this.getClass().getResourceAsStream("/config/IPConstant.properties");
pps.load(new BufferedReader(new InputStreamReader(in, "UTF-8")));
} catch (IOException e) {
e.printStackTrace();
}
this.ENVIRONMENT = pps.getProperty("ENVIRONMENT");
this.DOMAIN = pps.getProperty("DOMAIN");
this.VERSION = pps.getProperty("VERSION");
}
//静态内部类
private static class LazyHolder {
private static final ConfigSingleton INSTANCE = new ConfigSingleton();
}
//暴露出来的获取单例对象的静态方法
public static final ConfigSingleton getInstance() {
return LazyHolder.INSTANCE;
}
}

  测试类代码

public class SingletonTest {
public static void main(String args[]){
System.out.println(ConfigSingleton.getInstance().getDOMAIN());
System.out.println(ConfigSingleton.getInstance().getENVIRONMENT());
System.out.println(ConfigSingleton.getInstance().getVERSION());
}
}

  测试结果

  扩展思维

  在一个jvm中会出现多个单例吗

  在分布式系统、多个类加载器、以及序列化的的情况下,会产生多个单例,这一点是无庸置疑的。那么在同一个jvm中,会不会产生单例呢?使用单例提供的getInstance()方法只能得到同一个单例,除非是使用反射方式,将会得到新的单例。代码如下

public class SingletonTest {
public static void main(String args[]) throws Exception{
Class c = Class.forName(ConfigSingleton.class.getName());
Constructor ct = c.getDeclaredConstructor();
ct.setAccessible(true);
ConfigSingleton singleton = (ConfigSingleton)ct.newInstance();
System.out.println(singleton.getDOMAIN());
System.out.println("----------------------------------------");
System.out.println(ConfigSingleton.getInstance().getDOMAIN());
System.out.println(ConfigSingleton.getInstance().getENVIRONMENT()); }
}

  运行结果

  这样,每次运行都会产生新的单例对象。所以运用单例模式时,一定注意不要使用反射产生新的单例对象。

  单例模式注意事项:

  • 只能使用单例类提供的方法得到单例对象,不要使用反射,否则将会实例化一个新对象。
  • 不要做断开单例类对象与类中静态引用的危险操作。
  • 多线程使用单例使用共享资源时,注意线程安全问题。

参考:

http://blog.csdn.net/zhengzhb/article/details/7331369

http://www.cnblogs.com/shenliang123/archive/2012/03/26/2417968.html

GOF业务场景的设计模式-----单例模式的更多相关文章

  1. GOF业务场景的设计模式-----观察者模式

    定义:定义对象间一种一对多的依赖关系,使得当每一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新. 在软件系统中经常会有这样的需求:如果一个对象的状态发生改变,某些与它相关的对象也要随之做出 ...

  2. GOF业务场景的设计模式-----工厂模式

    定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类. 工厂方法模式 基本代码 interface IProduct { public void produ ...

  3. GOF业务场景的设计模式-----设计模式六大原则

    单一职责原则(Single Responsibility Principle) 定义:不要存在多于一个导致类变更的原因.通俗的说,即一个类只负责一项职责. 问题由来:类T负责两个不同的职责:职责P1, ...

  4. GOF业务场景的设计模式-----责任链模式

    定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止. 首先来看一段代码: public void tes ...

  5. GOF业务场景的设计模式-----策略模式

    定义:定义一组算法,将每个算法都封装起来,并且使他们之间可以互换. 策略模式代码实现 interface IStrategy { public void doSomething(); } class ...

  6. 【智能合约】编写复杂业务场景下的智能合约——可升级的智能合约设计模式(附Demo)

    智能合约的现状 以太坊在区块链上实现了智能合约的概念,用于:同质化通证发行(ERC-20).众筹.投票.存证取证等等,共同点是:合约逻辑简单,只是业务流程中的关键节点,而非整个业务流程.而智能合约想解 ...

  7. 《设计模式面试小炒》策略和工厂模式替代业务场景中复杂的ifelse

    <设计模式面试小炒>策略和工厂模式替代业务场景中复杂的ifelse 我是肥哥,一名不专业的面试官! 我是囧囧,一名积极找工作的小菜鸟! 囧囧表示:小白面试最怕的就是面试官问的知识点太笼统, ...

  8. 实践GoF的23种设计模式:SOLID原则(上)

    摘要:本文以我们日常开发中经常碰到的一些技术/问题/场景作为切入点,示范如何运用设计模式来完成相关的实现. 本文分享自华为云社区<实践GoF的23种设计模式:SOLID原则(上)>,作者: ...

  9. 实践GoF的23种设计模式:观察者模式

    摘要:当你需要监听某个状态的变更,且在状态变更时通知到监听者,用观察者模式吧. 本文分享自华为云社区<[Go实现]实践GoF的23种设计模式:观察者模式>,作者: 元闰子 . 简介 现在有 ...

随机推荐

  1. jquery插件-表单验证插件-demo

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. 【poj1741】 Tree

    http://poj.org/problem?id=1741 (题目链接) 题意 给出一个n个节点的带权树,求树上距离不超过K的所有点对的个数. solution  点分治裸题.所谓的点分治,就是对于 ...

  3. JS监听DOM结构变化

    在做一个微博的接入,需要判断微博是否被关注,要检查微博标签的DIV是否有“已关注”的字符,但这个DIV的内容是微博JSSDK动态生成.$("#id").html()是获取不到我想要 ...

  4. 组合数取模Lucas定理及快速幂取模

    组合数取模就是求的值,根据,和的取值范围不同,采取的方法也不一样. 下面,我们来看常见的两种取值情况(m.n在64位整数型范围内) (1)  , 此时较简单,在O(n2)可承受的情况下组合数的计算可以 ...

  5. Python之禅+八荣八耻

    Python之禅 (The Zen of Python):是Python语言的指导原则,可以在Python命令行输入import this显示. import this >>> Th ...

  6. sstream使用简介

    sstream即字符串流.sstream有三种类:ostringstream:用于输出操作,istringstream:用于输入操作,stringstream:用于输入输出操作其实我感觉只用第三个就够 ...

  7. IAR使用记录

    1. Project-->Options... 更改器件:General-->Target-->Device 添加其它需包含的目录:C/C++ Compiler-->Prepr ...

  8. [IOS 静态库]

    http://www.2cto.com/kf/201402/276718.html 一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 二.静态库与动态库的区别? 静态库:链接时完整地拷 ...

  9. JZOJ P1817:[8.27]研究性学习作业

    传送门 老师良心推荐的二分题.7月29号第一次写,想到了裸的DP,乱搞搞过了6组,欲优化,无解,弃疗. 然后今天老师给了题解,简单看了一下. 正解是二分答案+DP验证. 二分天数$day$,然后对于每 ...

  10. python的正则表达式 re-------可以在字符串前加上 r 这个前缀来避免部分疑惑,因为 r 开头的python字符串是 raw 字符串,所以里面的所有字符都不会被转义

    正则表达式使用反斜杆(\)来转义特殊字符,使其可以匹配字符本身,而不是指定其他特殊的含义.这可能会和python字面意义上的字符串转义相冲突,这也许有些令人费解.比如,要匹配一个反斜杆本身,你也许要用 ...