GOF业务场景的设计模式-----单例模式
个人觉得 纯粹的学习设计模式,是不对的。也不能为了使用设计模式,而硬搬设计模式来使用
单例模式可能是 最简单的设计模式也是 大家知道最多的设计模式。当然 ,有很多种写法
定义:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
业务场景
很多时候,我们的系统需要 很多的一些常量数据,这些数据在不同的环境下可能会不同。但是一旦确定了运行环境,这些配置常量,就不会改变。
我们在代码中需要用到这些常量,如果每一次使用,都从配置文件中读取,这样会损耗大量的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业务场景的设计模式-----单例模式的更多相关文章
- GOF业务场景的设计模式-----观察者模式
定义:定义对象间一种一对多的依赖关系,使得当每一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新. 在软件系统中经常会有这样的需求:如果一个对象的状态发生改变,某些与它相关的对象也要随之做出 ...
- GOF业务场景的设计模式-----工厂模式
定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类. 工厂方法模式 基本代码 interface IProduct { public void produ ...
- GOF业务场景的设计模式-----设计模式六大原则
单一职责原则(Single Responsibility Principle) 定义:不要存在多于一个导致类变更的原因.通俗的说,即一个类只负责一项职责. 问题由来:类T负责两个不同的职责:职责P1, ...
- GOF业务场景的设计模式-----责任链模式
定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止. 首先来看一段代码: public void tes ...
- GOF业务场景的设计模式-----策略模式
定义:定义一组算法,将每个算法都封装起来,并且使他们之间可以互换. 策略模式代码实现 interface IStrategy { public void doSomething(); } class ...
- 【智能合约】编写复杂业务场景下的智能合约——可升级的智能合约设计模式(附Demo)
智能合约的现状 以太坊在区块链上实现了智能合约的概念,用于:同质化通证发行(ERC-20).众筹.投票.存证取证等等,共同点是:合约逻辑简单,只是业务流程中的关键节点,而非整个业务流程.而智能合约想解 ...
- 《设计模式面试小炒》策略和工厂模式替代业务场景中复杂的ifelse
<设计模式面试小炒>策略和工厂模式替代业务场景中复杂的ifelse 我是肥哥,一名不专业的面试官! 我是囧囧,一名积极找工作的小菜鸟! 囧囧表示:小白面试最怕的就是面试官问的知识点太笼统, ...
- 实践GoF的23种设计模式:SOLID原则(上)
摘要:本文以我们日常开发中经常碰到的一些技术/问题/场景作为切入点,示范如何运用设计模式来完成相关的实现. 本文分享自华为云社区<实践GoF的23种设计模式:SOLID原则(上)>,作者: ...
- 实践GoF的23种设计模式:观察者模式
摘要:当你需要监听某个状态的变更,且在状态变更时通知到监听者,用观察者模式吧. 本文分享自华为云社区<[Go实现]实践GoF的23种设计模式:观察者模式>,作者: 元闰子 . 简介 现在有 ...
随机推荐
- C语言的时间函数
下面是C语言的获取本地时间和构造时间进行格式化时间显示输出的相关函数:This page is part of release 3.35 of the Linux man-pages project. ...
- 洛谷P1808 单词分类
题目描述 Oliver为了学好英语决定苦背单词,但很快他发现要直接记住杂乱无章的单词非常困难,他决定对单词进行分类. 两个单词可以分为一类当且仅当组成这两个单词的各个字母的数量均相等. 例如“AABA ...
- C#制作验证码
void CodeImage(string code) { if (code == null || code.Trim() == string.Empty) return; System.Drawin ...
- java编译错误 程序包javax.servlet不存在javax.servlet.*
java编译错误 程序包javax.servlet不存在javax.servlet.* 编译:javac Servlet.java 出现 软件包 javax.servlet 不存在 软件包javax. ...
- javascript应用之如何判断一个数为素数
判断是否为素数? 质数(prime number)又称素数,有无限个.质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数的数称为质数. 合数,数学用语,英文名为Composite numb ...
- python 遍历文件夹 文件
python 遍历文件夹 文件 import os import os.path rootdir = "d:\data" # 指明被遍历的文件夹 for parent,dirn ...
- 数组Arrays
1.toString 方法 Arrays的toString方法可以方便的输出一个数组的字符串形式,方便查看,它有九个重载的方法,包括八种基本类型数组和一个对象类型数组,这里列举两个: public s ...
- SQL Server 2012 学习笔记3 增查改删
现在举例几个"增查改删"的语句 select * from UserInfor --查找所有字段 select username,UserId from UserInfor -- ...
- sed delete
sed -i '1d' a.txt删首行 sed -i '$d' b.txt删尾行 sed -i 's/[ ]//g' c.txt删空格 sed -i '/^$/d' d.txt删空行 sed -i ...
- python 五子棋
http://www.skywind.me/blog/archives/1029 http://blog.csdn.net/skywind/article/details/8164713 https: ...