Android 应用最广泛的模式——单例模式

● 单例模式介绍
单例模式是应用最广的模式之一,也可能是很多初级工程师唯一会使用的设计模式。在应用这个模式时,代理对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个全局对象,这样又利于我们协调系统整体的行为。如在一个应用中,应该只有一个ImageLoader实例,这ImageLoader中又含有线程池、缓存系统、网络请求等。很消化资源,因此,没有理由让它构造多个实例。这种不能自由构造对象的情况,就是单例模式的使用场景。
● 单例模式的定义
确保某一个类只有一个实例,而且自行实例化并像这个系统提供这个实例。
● 单例模式的使用场景
确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源,或者某种类型的对象只应该有且只有一个。例如,创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源,这时就要考虑单例模式。
● 单例模式UML类图
Android 应用最广泛的模式——单例模式
文章图片

角色介绍:
(1)Client——高层客户端;
(2)Singlet——单例类。
实现单例模式主要如下几个关键点:
(1)构造函数不对外开放,一般为Pirvate;
(2)通过一个静态方法或者枚举返回单例类对象;
(3)确保单例类的对象有且只有一个,尤其在多线程环境下;
(4)确保单例类对象在反序列化时不会重新构建对象。
通过见单例类的构造函数私有化,使得客户端代码不能通过new的形式手动构建单例类的对象。单例类会暴露一个公有的静态方法,客户端需要调用这个静态方法获取到单例类的唯一对象,在获取这个单例对象的过程中需要确保线程安全,即在多线程环境下构造单例类的对象也是有且只有一个,这也是单例模式实现中比较困难的地方。
● 单例模式的简单示例
单例模式是设计模式中比较简单的,只有一个单例类,没有其他的层次结构与抽象。该模式需要确保该类只能生成一个对象,通常是该类需要消耗较多的资源或者没有多个实现的情况。例如一个公司只有一个CEO、一个应用只有一个Appliacton对象等。下面以公司里的CEO为例来简单演示一下,一个公司可以有几个VP、无数个员工,但是CEO只有一个,请看下面示例。

//普通员工 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 ArrayList allStaffs = new ArrayList<>(); public void addStaff(Staff per) { allStaffs.add(per); } public void showAllstffs() { for (Staff per : allStaffs) { System.out.println("obj : "+per.toString()); } }} public static void main(String[] args) { Company cp = new Company(); Staff ceo1 = CEO.getCeo(); Staff ce02 = CEO.getCeo(); cp.addStaff(ceo1); cp.addStaff(ce02); //通过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.showAllstffs(); }

输出结果如下:
obj : text.CEO@7852e922 obj : text.CEO@7852e922 obj : text.VP@4e25154f obj : text.VP@70dea4e obj : text.Staff@5c647e05 obj : text.Staff@33909752 obj : text.Staff@55f96302

【Android 应用最广泛的模式——单例模式】从上述代码中可以看到,CEO类不能通过new的形式构建对象,只能通过CEO.getCEO()函数来获取,而这个CEO对象是静态对象,并且在声明的时候就已经初始化,这就保证了CEO对象的唯一性。从输出结果中发现,CEO两次输出的CEO对象都是一样的,而VP、Staff等类型的对象都是不同的。这个实现的核心在于将CEO类的构造方法私有化,使得外部程序不能通过构造函数来构造CEO对象,而CEO类通过一个静态方法返回一个静态对象。

    推荐阅读