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

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

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

  

  业务场景

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

  我们在代码中需要用到这些常量,如果每一次使用,都从配置文件中读取,这样会损耗大量的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. 判断IE和Edge

    //判断是否是IE浏览器,包括Edge浏览器function IEVersion() { var userAgent = navigator.userAgent; if (!!window.Activ ...

  2. 前端rem单位的使用研究

    分析网易新闻手机web端,http://3g.163.com/,发现里面大量使用了rem这个单位进行计算大小. 针对rem这个单位有如下解析: px:像素是相对于显示器屏幕分辨率而言的相对长度单位.p ...

  3. C语言之流的重定向

    写c的小程序断不了需要输入输出,手动输入可太麻烦了.下面介绍IO的重定向方式: .重定向标准输入输出和错误,直接在命令行使用符号< > > >> >>等,还可 ...

  4. 洛谷P1595 信封问题

    题目描述 某人写了n封信和n个信封,如果所有的信都装错了信封.求所有信都装错信封共有多少种不同情况. 输入输出格式 输入格式: 一个信封数n 输出格式: 一个整数,代表有多少种情况. 输入输出样例 输 ...

  5. [小技巧] shell 下查看串口是否工作正常

    在 Linux 下调试串口,是个麻烦的事情,尤其是嵌入式环境,很多时候要借助另一台设备来进行调试. 这里琢磨出一种可行的串口调试方法,可以简单的查看串口是否在正确工作. 1. 短接 tx 和 rx,让 ...

  6. POJ 1061青蛙的约会(拓展欧几里德算法)

    题目链接: 传送门 青蛙的约会 Time Limit: 1000MS     Memory Limit: 65536K Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见 ...

  7. django models auto_now和auto_now_add的区别

    DataTimeField()中auto_now参数和auto_now_add参数区别: 前者添加或者修改的都为现在的时间,可以再次更新: 后者仅仅为添加时候的时间,不可更改.

  8. django redis操作

    from utils.redis.connect import redis_cache as rr.flushdb() 列表操作 r.lpush("name", xxxx) or ...

  9. 【Beta版本】冲刺-Day2

    队伍:606notconnected 会议时间:12月10日 目录 一.行与思 二.站立式会议图片 三.燃尽图 四.代码Check-in 一.行与思 张斯巍(433) 今日进展:对登录界面做了相应的修 ...

  10. 使用chrome查看网页上效果的实现方式

    使用chrome查看网页上效果的实现方式 chrome是一个极为强大的工具,很多时候,我们不知道一个效果怎么实现的,我们完全可以找到响应的网页,然后找到其html文件,和js文件,查看源码,获得其实现 ...