Java面向对象——设计模式(二)
5.5设计模式
5.5.1什么是设计模式?
- 在所有语言的编程过程中,根据前人的经验总结,总结出来了23种应对不同需求的代码编写经验。设计模式在知识体系不断完整的过程中,会不断发生改变。
5.5.2单例模式
i.单例模式(构建模式)
- 专门负责产生对象的。单例模式的核心是:每个类只能产生一个对象。
ii.单例模式的应用场景
- 计算机中的任务管理器。
- Spring中的bean也是单例的。
- MyBatis中的SessionFactory也是单例的。
- Runtime类也是单例的。
iii.编写单例模式
(1)饿汉式单例
public class HungrySingle{
private static HungrySingle hs=new HungrySingle();
private HungrySingle(){
System.out.println("我是一个被封装的构造器");
}
public static HungrySingle getInstance(){
return hs;
}
}
public class Test01{
public static void main(String[] args){
HungrySingle hs1=HungrySingle.getInstance();
HungrySingle hs2=HungrySingle.getInstance();
HungrySingle hs3=HungrySingle.getInstance();
System.out.println(hs1+"==="+hs2);
System.out.println(hs3);
}
}
执行结果:
我是一个被封装的构造器
com.pxcoder.myproject4.HungrySingle@15db9742===com.pxcoder.myproject4.HungrySingle@15db9742
com.pxcoder.myproject4.HungrySingle@15db9742
- 构造器私有,对外提供一个方法可以获取到当前类的实例。
- 通过静态内容只能被加载一次的特征,然后编写静态的成员变量。让第一次类加载时将当前类的对象创建出来,后续直接使用当前创建出来的对象即可。
- 饿汉式单例最大的问题是:不能做到延迟加载。最大的优势在于:线程天然安全。
(2)懒汉式单例
public class LazySingle{
private static LazySinglels=null;
private LazySingle(){
System.out.println("我是一个被封装了的构造器");
}
public static LazySingle getInstance(){
if(ls==null){
ls=newLazySingle();
}
return ls;
}
}
public class Test01{
public static void main(String[] args){
LazySingle hs1=LazySingle.getInstance();
System.out.println(hs1);
LazySingle hs2=LazySingle.getInstance();
System.out.println(hs2);
}
}
我是一个被封装了的构造器
com.pxcoder.myproject4.LazySingle@15db9742
com.pxcoder.myproject4.LazySingle@15db9742
- 构造器私有,对外提供一个方法可以获取到当前类的实例。
- 通过静态内容只能被加载一次的特征,然后编写静态的成员变量。让第一次类加载时不创建类的所属对象。等到调用静态方法时才将对象创建出来。
- 懒汉式单例最大的问题是:线程天然不安全最大的优势在于:到延迟加载
(3)静态内部类完成单例
public class StaticSingle{
private static class SingleHolder{
private static StaticSingle ss=new StaticSingle();
}
private StaticSingle(){
System.out.println("我是外部类构造器方法");
}
public static StaticSingle getInstance(){
return SingleHolder.ss;
}
}
public class Test01 {
public static void main(String[] args) {
StaticSingle ss1=StaticSingle.getInstance();
StaticSingle ss2=StaticSingle.getInstance();
System.out.println(ss1+"="+ss2);
}
}
//执行结果:
我是外部类构造器方法
com.pxcoder.myproject4.StaticSingle@15db9742=com.pxcoder.myproject4.StaticSingle@15db9742
- 只有调用getInstance时才加载了SingleHolder这个类,所以可以做到延迟加载。
- 静态内部类而言它首先是一个类其次才是外部类的一个静态内容。
- 外部类的加载不会导致静态内部类的加载。
- 特点是:天然线程安全的,可以延迟加载。(static修饰的,有且只加载一次。)