《Head First 设计模式》学习笔记——单件模式

设计模式

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

要点

单件模式确保程序中一个类最多只有一个实例。

在Java中实现单件模式需要私有的构造器、一个静态方法、一个静态变量。

确定在性能和资源上的限制,然后小心翼翼的选择适当的方案来实现单件,以解决多线程问题。

全局变量缺点

如果将对象赋值给一个全局变量,那么必须在程序一开始就创建好对象。万一对象非常耗费资源,而程序在这次执行过程中并没有使用它,就形成了浪费。

单件模式

public class Singleton {
	//利用一个静态变量来记录Singleton类的唯一实例
	private static Singleton uniqueInstance;

	//把构造器声明为私有,没有公开的构造器,避免了产生多个实例。需要获得实例时,调用Singleton.getInstance().
	private Singleton() {
	}

	//静态方法,是一个“类”的方法。引用一个静态方法,只需要使用类名,不需要对象名
	public static Singleton getInstance() {
		if (uniqueInstance == null) {
			uniqueInstance = new Singleton();
		}
		return uniqueInstance;
	}

}

如何改善多线程?

(1)如果使用getInstance()的性能对应用程序不是很关键,那就使用即简单又方便的同步getInstance()。虽然程序执行效率可能会下降100倍。

public class Singleton {
	private static Singleton uniqueInstance;

	private Singleton() {
	}

	//增加synchronzed关键字到该方法中,迫使每个线程进入这个方法之前,要先等候别的线程离开该方法。
	public static synchronzed Singleton getInstance() {
		if (uniqueInstance == null) {
			uniqueInstance = new Singleton();
		}
		return uniqueInstance;
	}
}

(2)使用急切的创建实例,而不用延迟实例化的做法。

public class Singleton {
	//在静态初始器中定创建单件。这段代码保证了线程安全
	private static Singleton uniqueInstance = new Singleton();

	private Singleton() {
	}

	public static Singleton getInstance() {
		//已经有了实例,直接使用
		return uniqueInstance;
	}
}

(3)用“双重检查加锁”,在getInstance()中减少使用同步。

首先检查实例是否已经创建,如果尚未创建,才同步。不适用于1.4及更早版本。

public class Singleton {
	//volatile关键字确保当uniqueInstance变量被初始化成Singleton实例时,多个线程正确的处理该变量
	private volatile static Singleton uniqueInstance;

	private Singleton() {
	}

	public static Singleton getInstance() {
		//检查实例,如果不存在,就不进入
		if (uniqueInstance == null) {
			synchronized (Singleton.class) {
				//进入区块后再检查一次。如果仍是null,才创建实例。
				if (uniqueInstance == null) {
					uniqueInstance = new Singleton();
				}
			}
		}
		return uniqueInstance;
	}
}

《Head First 设计模式》学习笔记——单件模式

时间: 2024-10-10 09:43:58

《Head First 设计模式》学习笔记——单件模式的相关文章

设计模式学习笔记--外观模式

好久没写设计模式的blog了,这次重新回来填坑,先找一个最简单但是却最常用的设计模式来学习,外观模式.其实说是一个设计模式,其实我们在实际的编程中无时无刻不在用外观模式,可以说这个设计模式已经渗透到编程的各个方便,可能我们自己没感觉出来罢了. 一.外观模式的定义 先来看一下外观模式的定义: 外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层的接口,这个接口使得这一系列子系统更加容易使用. 简单解释一下,所谓外观模式,就是在我们设计系统的时候,将若干个子系统的功

设计模式学习笔记-工厂模式

一.概述 定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法(Factory Method)使一个类的实例化延迟到其子类: 2.模式中的角色 Product(Map):定义工厂方法所创建的对象的接口. ConcreteProduct(BaiduMap.GaodeMap):具体Product,实现Product接口. Creator(IMapFactory):声明工厂方法,该方法返回一个Product类型的对象. ConcreteCreator(BaiduMapFactory.Gaod

设计模式学习笔记-桥接模式

一.概述 将抽象部分与它的实现部分分离,使它们都可以独立地变化. 二.模式中的角色 Abstraction:定义抽象类的接口:维护一个指向Implementor类型对象的指针: RefinedAbstraction:扩充由Abstraction定义的接口: Implementor:定义具体行为,具体特征的应用接口: ConcreteImplementor:实现Implementor. 三.UML类图 四.代码实现 4.1 桥接模式的实现代码 /// <summary> /// 实现 /// &

设计模式学习笔记-建造者模式

一.概述 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示: 二.模式中的角色 Builder:为创建一个Product对象的各个部件指定抽象接口: ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件:定义并明确它所创建的表示:提供一个检索产品的接口: Director:构造一个使用Builder接口的对象: Product:表示被构造的复杂对象,ConcreteBuilder创建该产品的内部表示并定义它的装配过程:包含定义组成部件的类,

设计模式学习笔记--策略模式

定义: 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 我们在使用一些功能时,有时有很多种实现方法,或者多种结果,但是都有同样的使用方法,即调用接口,这就是策略模式. 例子: // 设计模式Demo.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #include <string> using namespa

Java-马士兵设计模式学习笔记-命令模式

一.概述 命令模式 二.代码 1.Client.java 1 public class Client { 2 3 public void request(Server server){ 4 server.addCommand(new TextCommand()); 5 server.addCommand(new ImageCommand()); 6 server.doSomething(); 7 } 8 } 2.Server.java 1 public class Server { 2 3 pr

设计模式学习笔记——组合模式

组合模式 组合模式,将对象组合合成树形结构以表示"部分-整体"的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性. 代码实现 接口声明Component /** * 接口声明 * @author xukai 2016年3月26日 下午4:58:37 * */ public abstract class Component { protected String name; public Component(String name) { this.name = name; }

设计模式读书笔记-单件模式(创建型模式)

让一个类只有一个对象,全局唯一 非多线程模式,实现方法: 方法1: 1 public class SingletonTest 2 { 3 public static readonly SingletonTest Instance = new SingletonTest(); 4 private SingletonTest() { } 5 } 方法2: 1 public class SingletonTest 2 { 3 public static readonly SingletonTest I

Java-马士兵设计模式学习笔记-桥接模式

一.概述 1.桥接模式的应用情况:(1)两个维度扩展(2)排列组合 二.代码 1.Gift.java 1 public class Gift { 2 3 protected GiftImpl giftImpl; 4 } 2.GiftImpl.java 1 public class GiftImpl { 2 3 } 3.WarmGift.java 1 public class WarmGift extends Gift { 2 3 public WarmGift(GiftImpl giftImpl