[学习笔记]Java模板方法和单例设计模式

来源:互联网 发布:ajax传递对象数组 编辑:程序博客网 时间:2024/06/05 03:10

模板方法

概念

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。TemplateMethod 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。还可以使用Hook操作扩展超类(父类)的算法框架。

要点

1. 模板方法不允许被复写,所以需要被final修饰,其中定义了操作算法的骨架,必须而又不确定的步骤定义为抽象方法。
2. 模板方法中的非必须的步骤或者有默认实现的步骤可以定义为钩子,钩子也可以用来作为条件控制流程实现。
3. 模板方法类中一定有一个final模板方法,一个或多个abstract方法,以及非必须的钩子hook方法。

实例

/**
* 获取程序方法的运行时间,通过模板方法实现。
*/
abstract class GetTime {
// 模板方法,实现具体算法骨架,不确定的部分由子类定义。
public final long getTime() {
long startTime = System.nanoTime();
run();
long estimatedTime = System.nanoTime() - startTime;
 
if (isPrinted()) {
System.out.println("Estimated Time is " + estimatedTime + " nanoseconds.");
}
return estimatedTime;
}
 
// 具体的实现方法使用抽象方法,让子类决定
abstract void run();
 
// 这是一个hook,可以由子类扩展功能,该方法是可选的,默认是true
public boolean isPrinted() {
return true;
}
}
class ConcreteGetTime extends GetTime {
// 子类确定具体要计算运行时间的方法,这里复写父类的抽象方法
public void run() {
int x = 0;
for (int i = 0; i < 10000; i++) {
x++;
}
}
}
public class TemplateMethod {
public static void main(String[] args) {
ConcreteGetTime t = new ConcreteGetTime();
t.getTime();
}
}

单例

概念

解决一个类在内存中只存在一个对象的问题。
1. 禁止其他程序建立该类对象。
2. 为了让其他程序可以访问到该类对象,在本类中自定义一个对象。
3. 为了方便其他程序对自定义对象访问,可以对外提供访问方式。

具体实现

1. 构造函数私有化。
2. 类中创建一个本类对象。
3. 提供一个方法可以获取对象。
其中,先初始化对象,称为“饿汉式”;方法被调用时初始化对象,即对象的延时加载,称为“懒汉式”
建议使用“饿汉式”

要点

1. 单例模式确保程序中一个类最多只有一个实例。
2. 单例模式也提供访问这个实例的全局点。
3. Java中实现单例模式需要有私有的构造器,一个静态方法和一个静态变量。
4. 确定在性能和资源上的限制,以此选择适当的方法实现单例,以解决多线程问题。
5. 双重检查加锁方法只适用于Java 1.5及以上版本支持。
6. 如果使用多个类加载器,小心哦,可能导致单例失效产生多个实例。
7. 如果使用Java1.2及以前版本,必须建立单件注册表。

示例

/**
* 饿汉式单例
*/
class Single {
private int num;
// 该类的静态实例
private static Single s = new Single();
 
// 私有的构造器
private Single() {}
 
// 获取该类实例的静态方法
public static Single getInstance() {
return s;
}
 
public void setNum(int num) {
this.num = num;
}
 
public int getNum() {
return this.num;
}
}
class Singlelan {
private int num;
// volatile确保:s当初始化为Singlelan实例时,多个线程正确地处理s变量。
// Java5支持
private volatile static Singlelan s = null;
 
private Singlelan() {}
 
public static Singlelan getInstance() {
// 利用双重检查加锁方法,在getInstance方法中减少使用同步。
if (s == null) {
synchronized (Singlelan.class) {
if (s == null) s = new Singlelan();
}
}
return s;
}
 
public void setNum(int num) {
this.num = num;
}
 
public int getNum() {
return this.num;
}
}
class SingleDemo {
public static void main(String[] args) {
Single s1 = Single.getInstance();
Single s2 = Single.getInstance();
s1.setNum(8);
System.out.println("s1 = " + s1 + " \ts1.num = " + s1.getNum());
System.out.println("s2 = " + s2 + " \ts2.num = " + s2.getNum());
}
}
0 0
原创粉丝点击