Android常见的设计模式一:单例模式

对于设计模式,我个人认为如果整篇写原理的话,应该很乏味有难懂,所以我比较喜欢白话似的解释和代码的结合。废话不多说。

本文首先介绍常见的设计模式之一:单例模式。
 单例模式是一种对象创建性模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在一个实例对象。
单例模式的要点有三个:
  • 某个类只能有一个实例;
  • 必须自行创建整个实例;
  • 必须自行向整个系统提供整个实例。
下面介绍单例模式的三个版本:
 1.“饿汉式”,也就是当类加载进来的就立即实例化对象,但是这种方式比较的消耗计算机资源。 
public class SingleTonFirst { 
// 在类被加载进入内存的时候就创建单一的Foo对象 
public static final SingleTonFirst first= new SingleTonFirst (); 
// 构造函数私有化 
private SingleTonFirst () { 
} 
// 提供一个全局的静态方法 
public static SingleTonFirst getSingleTonFirst () { 
return first; 
} 
}
2.“懒汉式”,在单线程下能够非常好的工作,但是在多线程下存在线程安全问题。
// 这种方式在需要使用的时候才实例化 
public class SingleTonTwo{ 
private static SingleTonTwo two; 
// 构造函数私有化 
private SingleTonTwo () { 
} 
// 提供一个全局的静态方法 
public static SingleTonTwo getSingleTonTwo () { 
if (two== null) { 
two= new SingleTonTwo (); 
} 
return two; 
} 
} 
3.第三个版本:为解决多线程问题,采用了对函数进行同步的方式,但是比较浪费资源,因为每次都要进行同步检查,而实际中真正需要检查只是第一次实例化的时候.
public class SingleTonThree{
    private static SingleTonThree three;

    // 构造函数私有化
    private SingleTonThree() {
    }

    // 提供一个全局的静态方法,使用同步方法
    public static synchronized SingleTonThree getSingleTonThree() {
        if (three== null) {
            three= new SingleTonThree();
        }
        return three;
    }
}
4.第四个版本:既解决了”懒汉式“的多线程问题,又解决了资源浪费的现象,看上去是一种不错的选择。
public class SingleTonFour{
    private static SingleTonFour four;

    // 构造函数私有化
    private SingleTonFour() {
    }

    // 提供一个全局的静态方法
    public static SingleTonFourgetSingleTonFour() {
        if (four== null) {
            synchronized (SingleTonFour.class) {
                if (four== null) {
                    four= new SingleTonFour();
                }
            }
        }
        return four;
    }
}

在Android中,很多地方用到了单例。
比如Android-Universal-Image-Loader中的单例

private volatile static ImageLoader instance;
/** Returns singleton class instance */
public static ImageLoader getInstance() {
    if (instance == null) {
        synchronized (ImageLoader.class) {
            if (instance == null) {
                instance = new ImageLoader();
            }
        }
    }
    return instance;
}

比如EventBus中的单例

private static volatile EventBus defaultInstance;
public static EventBus getDefault() {
    if (defaultInstance == null) {
        synchronized (EventBus.class) {
            if (defaultInstance == null) {
                defaultInstance = new EventBus();
            }
        }
    }
    return defaultInstance;
}

上面的单例都是比较规规矩矩的,当然实际上有很多单例都是变了一个样子,单本质还是单例。
如InputMethodManager 中的单例

static InputMethodManager sInstance;
public static InputMethodManager getInstance() {
    synchronized (InputMethodManager.class) {
        if (sInstance == null) {
            IBinder b = ServiceManager.getService(Context.INPUT_METHOD_SERVICE);
            IInputMethodManager service = IInputMethodManager.Stub.asInterface(b);
            sInstance = new InputMethodManager(service, Looper.getMainLooper());
        }
        return sInstance;
    }
}

AccessibilityManager 中的单例,看代码这么长,其实就是进行了一些判断,还是一个单例

private static AccessibilityManager sInstance;
public static AccessibilityManager getInstance(Context context) {
    synchronized (sInstanceSync) {
        if (sInstance == null) {
            final int userId;
            if (Binder.getCallingUid() == Process.SYSTEM_UID
                    || context.checkCallingOrSelfPermission(
                            Manifest.permission.INTERACT_ACROSS_USERS)
                                    == PackageManager.PERMISSION_GRANTED
                    || context.checkCallingOrSelfPermission(
                            Manifest.permission.INTERACT_ACROSS_USERS_FULL)
                                    == PackageManager.PERMISSION_GRANTED) {
                userId = UserHandle.USER_CURRENT;
            } else {
                userId = UserHandle.myUserId();
            }
            IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
            IAccessibilityManager service = IAccessibilityManager.Stub.asInterface(iBinder);
            sInstance = new AccessibilityManager(context, service, userId);
        }
    }
    return sInstance;
}

最后,我们应用一下单例模式。典型的一个应用就是管理我们的Activity,下面这个可以作为一个工具类,代码也很简单,也不做什么解释了。

public class ActivityManager {

    private static volatile ActivityManager instance;
    private Stack<Activity> mActivityStack = new Stack<Activity>();

    private ActivityManager(){

    }

    public static ActivityManager getInstance(){
        if (instance == null) {
        synchronized (ActivityManager.class) {
            if (instance == null) {
                instance = new ActivityManager();
            }
        }
        return instance;
    }

    public void addActicity(Activity act){
        mActivityStack.push(act);
    }

    public void removeActivity(Activity act){
        mActivityStack.remove(act);
    }

    public void killMyProcess(){
        int nCount = mActivityStack.size();
        for (int i = nCount - 1; i >= 0; i--) {
            Activity activity = mActivityStack.get(i);
            activity.finish();
        }

        mActivityStack.clear();
        android.os.Process.killProcess(android.os.Process.myPid());
    }
}

单例模式的优缺点分析
优点:客户端使用单例模式的实例的时候,只需要调用一个单一的方法即可生成一个唯一的实例,有利于节约资源。

缺点:首先单例模式很难实现序列化,这就导致采用单例模式的类很难被持久化,当然也很难通过网络传输;其次由于单例采用静态方法,无法在继承结构中使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值