使用泛型封装返回结果以及使用委托封装try-catch流程
有一个很常见的需求,服务端有一个 校验登陆的 方法,最开始只有一个布尔值,表示成功失败。
public bool UserValid(string name, string pwd)
{
//校验登陆
}
后来需求变更,需要返回 具体的User对象以及 登陆失败的原因。
方案一:返回标识 比如 0,1,2 或者是枚举 表示登陆状态,在界面上再转化为具体的 登陆成功,密码错误等。
方案二:在方法中添加 out message,返回错误信息。
方案三:服务端抛出对应异常,客户端捕获。
方案四:封装返回结果为一个类。
个人偏向方案四,但是如果每个返回结果都需要封装一个类,那不累死了?
所以 使用泛型封装出一个通用的返回结果
//定义返回状态
public enum RequestState
{
Non = 0,
Success = 1,
Other = 2
}
//返回结果类
public class Request<T>
{
public T Result { get; private set; }//具体结果
public RequestState State { get; private set; }//状态
public string ErrorMessage { get; private set; }//错误信息
public Request(T result, RequestState state, string errorMessage)
{
this.Result = result;
this.State = state;
this.ErrorMessage = errorMessage;
}
public Request(T result, RequestState state)
: this(result, state, "")
{
}
}
该类 包含三部分,泛型结果,状态枚举以及错误信息。
这时我们可以将 上面的方法签名改为
public Request<User> UserValid(string name, string pwd)
客户端调用的时候 大致代码,此处使用winform
try
{
this.Cursor = Cursors.WaitCursor;
Request<User> request = IUser.UserValid(name, pwd);
if (request.State == RequestState.Success)
{
//dosomething
}
else
{
MessageBox.Show(request.ErrorMessage);
}
}
catch (Exception e)
{
//catch
}
finally
{
this.Cursor = Cursors.Default;
}
一切运转良好。但是随着时间的推移,我们发现除了 dosomething处,其他的代码都是重复的,是时候再次封装了。
我们使用委托将不同的操作抽离出来,将相同的操作封装为一个委托方法。
void Execute<T>(Func<Request<T>> func, Action<Request<T>> action)
{
try
{
this.Cursor = Cursors.WaitCursor;
Request<T> request = func();
if (request.State == RequestState.Success)
{
action(request);
}
else
{
MessageBox.Show(request.ErrorMessage);
}
}
catch (Exception e)
{
//catch
}
finally
{
this.Cursor = Cursors.Default;
}
}
调用方法如下:
Execute<User>(() => IUser.UserValid(name,pwd), /*获取数据*/ user=>MessageBox.Show(user.Name)/*后续处理*/);
这就是我比较偏向方案四的原因,可以提供统一的接口规范。
我们成功的将try中的逻辑分离了出来,使得我们只需要关注具体的实现。
同样的将catch中的逻辑分离出来,根据捕获到的不同异常,做不同的处理,再次修改代码如下:
void Execute<T>(Func<Request<T>> func, Action<Request<T>> action, Action<Exception> cactch)
{
try
{
this.Cursor = Cursors.WaitCursor;
Request<T> request = func();
if (request.State == RequestState.Success)
{
action(request);
}
else
{
MessageBox.Show(request.ErrorMessage);
}
}
catch (Exception e)
{
cactch(e);//此处需要捕获不同的异常 ,显示不同的错误
}
finally
{
this.Cursor = Cursors.Default;
}
}
void Execute<T>(Func<Request<T>> func, Action<Request<T>> action)
{
Execute<T>(func, action, e => MessageBox.Show(e.Message));
}
调用方法:
Execute<User>(() => IUser.UserValid(name,pwd), /*获取数据*/ user=>MessageBox.Show(user.Name)/*后续处理*/,ex=>{
if (ex is SocketException)
{
//.......
}
else//最后所有的异常类型
{
MessageBox.Show(ex.Message);
}
});

浙公网安备 33010602011771号