使用场景
就拿我公司项目说吧,当有来回切换连接不同的硬件设备时,并且当切换时,有释放和加载的需求,这就需要一个管理器来管理不同类型的实例类,具体大家对号入座吧!
单例模式类型
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()方法了。
到这里,单例和策略模式的结合使用讲完了,各位如果觉得还可以,麻烦评论下哈,不吝赐教~

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

被折叠的 条评论
为什么被折叠?



