设计模式
设计模式是在大量的实践中总结和理论化之后的代码结构、编程风格、以及解决问题的思考方式。设计模式就像经典的棋谱,不同的棋局,我们使用不同的棋谱,免去我们自己再思考和摸索
单例模式
单例(单个实例)设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(在软件运行的时候,我们要保证某一个类只能有一个实例化对象)
单例模式有两种方式:饿汉式和懒汉式
- 两者最主要的区别在于创建对象的时机不同,饿汉式是在类加载就创建了对象实例,而懒汉式是在使用时才创建对象
- 饿汉式不存在线程安全问题,而懒汉式存在线程安全问题
- 饿汉式存在浪费资源的可能,因为如果程序员一个对象实例都没有使用,那么饿汉式创建的对象就浪费了
饿汉式
饿汉式的单例模式,只要类一加载,就会在其内部创建对象(饿汉式方式可能创建了对象但是没有使用)
饿汉式单例设计模式具体步骤如下:
- 构造器私有化,防止在类的外部直接通过
new
方法实例化对象 - 类的内部创建对象(该对象是静态的)
- 向外暴露一个静态的公共方法,
getInstance()
java
package com.jlctest.single;
public class SingleTon {
public static void main(String[] args) {
// 通过公共的静态方法可以获取对象(且只能是一个)
GirlFriend instance = GirlFriend.getInstance();
// GirlFriend.getInstance()重复执行,还是返回在类中创建的那个对象
}
}
// 有一个类,GirlFriend 使用饿汉式的单例设计模式 软件运行过程中只能实例化一个对象
class GirlFriend {
private String name;
// 2.在类的内部创建对象,设置为静态属性,我们后续的静态方法可以访问到
// 同时静态的方法,只会在类创建的时候初始化一次,后续不会重复初始化
private static GirlFriend gf = new GirlFriend("小红");
// 1.将构造器私有化
private GirlFriend(String name) {
this.name = name;
}
// 3.提供一个公共的static方法,返回gf对象
public static GirlFriend getInstance() {
return gf;
}
}
懒汉式
与饿汉式的单例模式不同,懒汉式的单例模式,只有在调用暴露的静态公共方法时,才会在类的内部创建实例(防止了饿汉式的情况:可能出现创建了对象但是没有使用),在后面再次调用时,会返回上次创建的对象(因为是静态属性),从而保证单例
懒汉式单例设计模式具体步骤如下:
- 构造器私有化,防止在类的外部直接通过
new
方法实例化对象 - 类的内部创建对象(该对象是静态的)
- 向外暴露一个静态的公共方法,
getInstance()
java
package com.jlctest.single;
public class SingleTon {
public static void main(String[] args) {
// 通过公共的静态方法可以获取对象(且只能是一个)
GirlFriend instance = GirlFriend.getInstance();
// GirlFriend.getInstance()重复执行,还是返回在类中创建的那个对象
}
}
// 有一个类,GirlFriend 使用懒汉式的单例设计模式 软件运行过程中只能实例化一个对象
class GirlFriend {
private String name;
// 2.在类的内部创建对象,设置为静态属性,我们后续的静态方法可以访问到
// 同时静态的方法,只会在类创建的时候初始化一次,后续不会重复初始化
private static GirlFriend gf;
// 1.将构造器私有化
private GirlFriend(String name) {
this.name = name;
}
// 3.提供一个公共的static方法,返回gf对象
public static GirlFriend getInstance() {
// 如果对象还没有创建,就创建一个对象
if(gf == null) {
gf = new GirlFriend("小红");
}
return gf;
}
}
模板模式
抽象模板模式
抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但是子类总体上会保留抽象类的行为方式
模板设计模式能解决的问题:
- 当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现
- 编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或多个方法留给其子类实现,这就是一种模板模式
设计一个抽象类(Template
),完成如下功能:
- 编写方法
calculateTime()
,用于计算某段代码的消耗时间 - 编写抽象方法
job()
- 编写一个子类
Sub
,继承抽象类Template
,并实现job()
方法 - 编写一个测试类,看看是否好用
java
package com.jlctest.abstract;
// 抽象父类
abstract class Template {
public abstract void job(); // 抽象方法
// 统计耗时时间,具体的实现方法,调用了job()抽象方法
public void calculateTime() {
// 统计当前时间距离 1970-1-1 0:0:0的时间差,单位为ms
long start = System.currentTimeMillis();
job(); // 体现了动态绑定机制
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start));
}
}
子类去继承父类,实现父类中的抽象方法:
java
package com.jlctest.abstract;
public class AA extends Template {
// 实现了父类中的抽象方法
@Override
public void job() {
long num = 0;
for(long i = 1; i <= 800000; i++) {
num += i;
}
}
}
在测试文件中执行:
java
package com.jlctest.abstract;
public class Test {
public static void main(String[] args) {
AA a = new AA();
a.calculateTime();
}
}