前言
空对象模式基本很少用到,空对象去取代空引用,主要目的是当数据是空引用时提供一种默认的处理方式。
1.一般情况处理空引用
空对象模式为了防止意外情况,无法获取到对象时可以触发默认的处理。虽然感觉这个设计模式的使用场景很少,但还是简单的讲解一下,首先模拟一个会用到空对象模式的场景,具体代码如下:
public enum SDKType
{
QQ,
WeChat,
Visitor,
}
public interface SDKModule
{
void InitSDK();
void Login();
}
public class WeChatSDK : SDKModule
{
public void InitSDK()
{
Console.WriteLine("微信SDK初始化");
}
public void Login()
{
Console.WriteLine("微信登陆");
}
}
public class QQSDK : SDKModule
{
public void InitSDK()
{
Console.WriteLine("腾讯SDK初始化");
}
public void Login()
{
Console.WriteLine("腾讯登陆");
}
}
public class VisitorSDK : SDKModule
{
public void InitSDK()
{
Console.WriteLine("游客SDK初始化");
}
public void Login()
{
Console.WriteLine("游客登陆");
}
}
public class SDKFactory
{
public bool isExistSdk(SDKType sdkType)
{
Console.WriteLine("判断SDK是否接入...");
return default;//别介意随便写的
}
public SDKModule GetSdkModule(SDKType sdkType)
{
switch (sdkType)
{
case SDKType.QQ:
if (isExistSdk(sdkType))
return new QQSDK();
return default;
case SDKType.Visitor:
if (isExistSdk(sdkType))
return new QQSDK();
return default;
case SDKType.WeChat:
if (isExistSdk(sdkType))
return new QQSDK();
return default;
default:
return default;
}
}
}
不使用空对象模式的情况下,可以返回default(default如果是引用类型返回Null,值类型会返回0,bool类型会返回false等等),为了防止调用对象函数时发生意外,应该先判断一下引用类型是不是空引用,具体代码如下:
//方案1
SDKModule sdkModule = new SDKFactory().GetSdkModule(SDKType.QQ);
if(sdkModule == null)
sdkModule.InitSDK();
else
Console.WriteLine("执行弹窗消息说明:初始化sdk失败");
//方案2
SDKModule sdkModule = new SDKFactory().GetSdkModule(SDKType.QQ);
sdkModule?.InitSDK();
如果判断出的引用是空引用,接下里要执行默认的处理,可以使用方案1,不然就可以使用语法糖就是方案2。如果对象检查是空引用,但又必须触发默认的处理,使用方案1又感觉很不舒服,只是为了调用sdk初始化,就需要去判断是否为空等等的操作。这时可以用空对象模式去调整代码。
2.使用空对象模式修改代码
空对象模式可以把意外情况统一默认的进行处理,比如代码获取到的引用值为空引用或者其他发生的错误,以上场景就是使用空对象模式原因,这里的话可以统一处理SDK初始化失败和登陆操作无法执行的默认方式,具体代码如下:
public class DefaultSDK : SDKModule
{
public void InitSDK()
{
Console.WriteLine("屏幕上弹窗消息:初始化sdk失败");
}
public void Login()
{
Console.WriteLine("sdk登陆失败");
}
}
public class SDKFactory
{
public bool isExistSdk(SDKType sdkType)
{
Console.WriteLine("判断SDK是否接入...");
return default;//别介意随便写的
}
public SDKModule GetSdkModule(SDKType sdkType)
{
switch (sdkType)
{
case SDKType.QQ:
if (isExistSdk(sdkType))
return new QQSDK();
return new DefaultSDK();
case SDKType.Visitor:
if (isExistSdk(sdkType))
return new QQSDK();
return new DefaultSDK();
case SDKType.WeChat:
if (isExistSdk(sdkType))
return new QQSDK();
return new DefaultSDK();
default:
return new DefaultSDK();
}
}
}
总结
1.空对象模式的优缺点
优点:可以去掉对null的检查,避免程序抛出NullPointerException异常。
缺点:多加一个空对象的类。
2.空对象模式使用场景
1.获取插件调用时。
2.SDK的初始化。