本节书摘来自异步社区《Android 源码设计模式解析与实战》一书中的第2章,第2.5节单例模式的简单示例,作者 何红辉 , 关爱民,更多章节内容可以访问云栖社区“异步社区”公众号查看
2.5 单例模式的简单示例
单例模式是设计模式中比较简单的,只有一个单例类,没有其他的层次结构与抽象。该模式需要确保该类只能生成一个对象,通常是该类需要消耗较多的资源或者没有多个实例的情况。例如,一个公司只有一个CEO、一个应用只有一个Application对象等。下面以公司里的CEO为例来简单演示一下,一个公司可以有几个VP、无数个员工,但是CEO只有一个,请看下面示例。
示例实现代码
package com.dp.example.singleton;
// 普通员工
public class Staff {
public void work() {
// 干活
}
}
// 副总裁
public class VP extends Staff {
@Override
public void work() {
// 管理下面的经理
}
}
// CEO,饿汉单例模式
public class CEO extends Staff {
private static final CEO mCeo = new CEO();
// 构造函数私有
private CEO() {
}
// 公有的静态函数,对外暴露获取单例对象的接口
public static CEO getCeo() {
return mCeo;
}
@Override
public void work() {
// 管理VP
}
}
// 公司类
public class Company {
private List<Staff> allStaffs = new ArrayList<Staff>();
public void addStaff(Staff per) {
allStaffs.add(per);
}
public void showAllStaffs() {
for (Staff per : allStaffs) {
System.out.println("Obj : " + per.toString());
}
}
}
public class Test {
public static void main(String[] args) {
Company cp = new Company() ;
// CEO对象只能通过getCeo函数获取
Staff ceo1 = CEO.getCeo() ;
Staff ceo2 = CEO.getCeo() ;
cp.addStaff(ceo1);
cp.addStaff(ceo2);
// 通过new创建VP对象
Staff vp1 = new VP() ;
Staff vp2 = new VP() ;
// 通过new创建Staff对象
Staff staff1 = new Staff() ;
Staff staff2 = new Staff() ;
Staff staff3 = new Staff() ;
cp.addStaff(vp1);
cp.addStaff(vp2);
cp.addStaff(staff1);
cp.addStaff(staff2);
cp.addStaff(staff3);
cp.showAllStaffs();
}
}
输出结果如下:
Obj : com.android.dp.book.chapter2.company.CEO@5e8fce95
Obj : com.android.dp.book.chapter2.company.CEO@5e8fce95
Obj : com.android.dp.book.chapter2.company.VP@8b3
Obj : com.android.dp.book.chapter2.company.VP@222d10
Obj : com.android.dp.book.chapter2.company.Staff@1aa488
Obj : com.android.dp.book.chapter2.company.Staff@3dfeca64
Obj : com.android.dp.book.chapter2.company.Staff@22998b08
从上述的代码中可以看到,CEO类不能通过new的形式构造对象,只能通过CEO.getCEO()函数来获取,而这个CEO对象是静态对象,并且在声明的时候就已经初始化,这就保证了CEO对象的唯一性。从输出结果中发现,CEO两次输出的CEO对象都是一样的,而VP、Staff等类型的对象都是不同的。这个实现的核心在于将CEO类的构造方法私有化,使得外部程序不能通过构造函数来构造CEO对象,而CEO类通过一个静态方法返回一个静态对象。