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()方法了。
到这里,单例和策略模式的结合使用讲完了,各位如果觉得还可以,麻烦评论下哈,不吝赐教~
更多相关文章
- 责任链模式在Android中的应用
- 再论Handler—Handler事件分发、Handler线程切换原理解析
- 从原理上粗略认知Android线程池(ThreadPoolExecutor)
- 小论设计模式及在Android中的应用
- Android(安卓)中的线程池
- Android异步任务的使用方法
- Android之MVVM架构指南(一):导语
- Activity生命周期前传-Android(安卓)中的进程模式
- [置顶] 【Bugly干货分享】关于 Android(安卓)N 那些你不知道的事