android 单例模式和策略模式的结合使用

本文详细解析了单例模式的四种类型及其实现方式,包括懒加载模式、双重校验锁、饿汉模式和静态内部类实现线程安全的单例模式,并结合策略模式展示了如何在实际项目中灵活运用。

使用场景

就拿我公司项目说吧,当有来回切换连接不同的硬件设备时,并且当切换时,有释放和加载的需求,这就需要一个管理器来管理不同类型的实例类,具体大家对号入座吧!

单例模式类型

1. 懒加载模式

懒加载模式是我们在android中最常用的模式,具有高效率高性能的优势,缺点就是在多线程操作时,会有线程不安全问题。
适用场景:只在主线程中操作,或者只在某个子线程操作。
懒加载模式代码

public class LazyLoad{
    private static LazyLoad INSTANCE;
    private LazyLoad(){}
    public static LazyLoad getInstance(){
        if(INSTANCE == null){
            INSTANCE = new LazyLoad();
        }
    }
}

注意:切记不要在getInstance()方法,或者在判断是否为null后,加synchronized字段,这样不但不能保证线程安全问题,而且还会导致性能严重下降

2. 双重校验锁

如果想保证线程安全,又实在想用synchronized这个字段的话,就可以考虑双重校验锁~

public class DoubleCheck{
    //注意此处加了关键字volatile
    private volatile static DoubleCheck INSTATNCE;
    private DoubleCheck(){}
    public static DoubleCheck getInstance(){
        if(INSTANCE == null){
            synchronized(DoubleCheck.class){
                if(INSTANCE == null){
                    INSTANCE = new DoubleCheck();
                }
                return INSTANCE;
            }
        }
        return INSTANCE;
    } 
}

3. 饿汉模式

饿汉模式表示手机系统启动app时,单例就被创建,也消除了线程安全问题。

public class HungryModel{
    private static HungryModel INSATNCE = new HungryModel();
    private HungryModel(){}
    public static HungryModel getInstance(){
        return INSTANCE;
    }
}

注意:此单例模式在app启动时就会常驻于内存中,如果此类中加载的资源比较多,就会导致app很卡,所以此模式适用于单例类加载资源不太多,也不用去管理它的内存消耗问题。

4. 通过静态内部类实现线程安全的单例模式

此模式避免了从系统启动时就加载此单例的情况,是懒加载和饿汉式加载的结合

public class StaticInnerModel{
    private StaticInnerModel(){}

    public static StaticInnerModel getInstance(){
        return StaticInnerHolder.INSTANCE;
    }

    private static class StaticInnerHolder{
        private static StaticInnerModel INSTANCE = new StaticInnerModel();
    } 
}

枚举单例模式

此模式除了能实现线程安全,高性能,还能防止反序列化重新创建新的对象,防止被反射攻击。

public enum EnumSingleton {
    INSTANCE{
        @Override
        protected void work() {
            System.out.println("你好,是我!");
        }

    };
    protected abstract void work();    //单例需要进行操作(也可以不写成抽象方法)
}

策略模式组成

1. 抽象策略模式

通常由一个接口或者抽象类实现,提供行为。

2. 具体策略模式

继承或者实现抽象策略的行为,并实现这些行为。

3. 环境角色

会有一个抽象策略的引用,然后根据需求得到某个具体策略的实例。

单例和策略结合

分析了几种单例模式,第四种最符合要求,然后结合策略模式如下:
抽象策略:

public interface Device{
    public void connectDevice();
    public void releaseDevice();
}

具体策略

public class DeviceTypeA implements Device{
    public class DeviceTypeA implements Device{
    private static final String TAG = "DeviceTypeA";
    public void connectDevice(){
        Log.e(TAG,"connect DeviceTypeA");
    }
    public void releaseDevice(){
        Log.e(TAG,"release DeviceTypeA");
    }
}
}
public class DeviceTypeB implements Device{
    private static final String TAG = "DeviceTypeB";
    public void connectDevice(){
        Log.e(TAG,"connect DeviceTypeB");
    }
    public void releaseDevice(){
        Log.e(TAG,"release DeviceTypeB");
    }
}

抽象策略管理器

public class DeviceManager{
    //------------带静态内部类的单例引用模式--------------
    private DeviceManager(){}
    private static class DeviceManagerHolder{
        private static DeviceManager instance = new DeviceManager();
    }
    public static DeviceManager getInstance(){
        return DeviceManagerHolder.instance;
    }

    //---------持有一个共同接口的引用-----------
    private Device device;
    private static final int FLAG_TYPE_A = 1;
    private static final int FLAG_TYPE_B = 2;

    public void connect(int flag){
        if(flag == FLAG_TYPE_A){
            if(device != null){
                if(!(device instanceof DeviceTypeA)){
                    device = new DeviceTypeA();
                }
            }else{
                device = new DeviceTypeA();
            }
        }else if(flag == FLAG_TYPE_B){
            if(device != null){
                if(!(device instanceof DeviceTypeB)){
                    device = new DeviceTypeB();
                }
            }else{
                device = new DeviceTypeB();
            }
        }
        device.connectDevice();
    }

    public void releaseDevice(){
        if(device != null){
            device.releaseDevice();
            device = null;
        }
    }
}

剩下的就是在UI中通过DeviceManager.getInstance()方法去调用releaseDevice()和connectDevice()方法了。

到这里,单例和策略模式的结合使用讲完了,各位如果觉得还可以,麻烦评论下哈,不吝赐教~

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值