13.3.1单例模式
单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点。适用于某个类只有一个对象,以避免产生多个对象消耗过多资源,及只应该有一个对象的场景。
如加载图片的ImageLoad对象、线程池对象、缓存对象、网络请求对象、数据库对象、文件对象、登录状态对象、日志对象,及一些公共数据对象,都可以用单例模式实现,这样也减少了静态和全局变量的使用。
APP向服务器端发请求的时候,有的页面会发送多个请求给服务器,这时如果网络或服务器端出错,会接连弹出多个提示框;这种提示框也可以使用单列模式创建,这样即使发送了多个请求,但只显示一个出错提示框,改善用户体验。
实现单例模式的方式有饿汉、懒汉和DCL方式,如考虑到多线程的情况,这些方式都有不足之处,在《Java并发编事程件》中,推荐以下方式实现:
public class Singleton {
private Singleton() {}
public static Singleton getInstance() {
return SingletonHolder.sInstance;
}
private static class SingletonHolder {
private static final SingletonsInstance = new Singleton();
}
}
第一次加载Singleton类时,不会初始化sInstance,只有在第一次调用Singleton的getInstance方法时,才会导致sInstance被初始化。在第一次调用getInstance方法时会导致虚拟机加载SingletonHolder类,这种方式不仅能确保线程安全,也能保证单例对象的唯一性,同时也延迟了单例的实例化。
Builder模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
此模式的使用场景:
(1)相同的方法,不同的执行顺序,产生不同的事件结果时。
(2)多个部件或零件,都可以装配到一个对象中,但产生的运行结果不相同时。
(3)当初始化一个对象特别复杂,如参数多,且很多参数都具有默认值时。
如Android中AlertDialog的初始化配置就使用了Builder模式,加载图片的库ImageLoader和HTTP请求的初始化配置等使用了Builder模式。
原型模式用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象。在Android中,可以通过Cloneable接口实现。
此模式的使用场景:
(1)类初始化需要消耗非常多的资源,如数据、硬件资源等时,通过原型拷贝避免这些消耗。
(2)通过new产生一个对象需要非常繁琐的数据准备或访问权限时,可以使用原型模式。
(3)一个对象需要提供给其他对象访问,而且各个调用者都可能需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。
如修改用户信息、购物车详情、订单详情和用户编辑的文本内容时等可使用原型模式。
原型模式的核心问题就是对原始对象进行拷贝,使用时需要注意:深、浅拷贝的问题。建议尽量使用深拷贝,避免操作副本时影响原始对象的问题。
工厂方法模式定义一个用于创建对象的接口,让子类决定将哪一个类实例化,使一个类的实例化延迟到其子类。
此模式的使用场景是在任何需要生成负责对象的地方,用new就可以完成创建的对象无需使用工厂模式。
如电商APP中,创建各类产品对象和各类订单对象时,就可以使用工厂模式。
代码示例:
public abstract classProduct {
Public abstract void method();
}
public classConcreteProductA extends class Product {
@Override
public void method() {
…
}
}
public classConcreteProductB extends class Product {
@Override
public void method() {
…
}
}
//@param clz 产品类型
//@return 具体的产品对象
public abstract classFactory {
public abstract TcreateProduct (Class clz);
}
public classConcreteFactory extends class Factory {
@Override
public abstract TcreateProduct (Class clz) {
Product p = null;
try{
p = (Product)Class.format(clz.getName()).newInstance();
}catch (Exception e) {
…
}
return (T) p;
}
}
public class Client {
public static void main(String args) {
Factory factory = newConcreteFactory();
Product p = factory. createProduct(ConcreteProductA.class);
}
}
参考:《Android源码设计模式解析与实战》
网友评论