自己开发的公众号,可以领取淘宝内部优惠券

问题

现在有一个FileStorageService类,继承自IStorageService,具体实现如下

public interface IStorageService
{
void WriteAllBytes(string path, byte[] buffer);
byte[] ReadAllBytes(string path);
} public class FileStorageService : IStorageService
{
public void WriteAllBytes(string path, byte[] buffer) {
File.WriteAllBytes(path, buffer);
} public byte[] ReadAllBytes(string path)
{
return File.ReadAllBytes(path);
}
}

假设调用其中任一一个方法出现异常,例如读写文件时候经常碰见的异常:IOException, DirectoryNotFoundException, FileNotFoundException,UnauthorizedAccessException… 甚至是 OutOfMemoryException

方案1-不是我的问题

IStorageService 不关心抛出的异常,那是使用者的职责。如此便将问题抛给了使用IStorageService接口的用户,它们必须要捕获有可能抛出的异常,往往一种偷懒的做法就是使用try catch语句将其包裹起来,如:

IStorageService myStorageService = Resolver.Resolve<IStorageService>();
try
{
myStorageService.ReadAllBytes("C:\stuff.data");
} catch (Exception exception)
{
// please don't write generic error messages like this, be specific
Logger.Log("Oops something went wrong: " + exception.Message);
}

catch exception并不是什么好主意,而且每次调用都需要使用try catch很不方便

方案2-创建新的异常类

一种改进的方法就是创建我们自己的异常类如StorageReadException,不管以后具体的实现如何变化,我们仅捕获特定的异常来进行异常处理

public class StorageReadException : Exception
{
public StorageReadException(Exception innerException)
: base(innerException.Message, innerException)
{
}
}

之前的FileStorageService实现更改为:

public byte[] ReadAllBytes(string path)
{
try
{
return File.ReadAllBytes(path);
}
catch (FileNotFoundException fileNotFoundException)
{
throw new StorageReadException(fileNotFoundException);
}
}

调用代码:

IStorageService myStorageService = Resolver.Resolve<IStorageService>();
try
{
myStorageService.ReadAllBytes(path);
}
catch (StorageReadException sre)
{
Logger.Log(String.Format("Failed to read file from path, {0}: {1}", path, sre.Message));
}

同样存在try catch 包裹问题,而且用户必须依赖一个新的异常类型

方案3-Try 模式并返回一个Complex Result

我们可以使用Try模式来避免用户使用try catch,Try模式类似C#里int方法

bool TryParse(string s, out int result),我们对接口进行更改

byte[] ReadAllBytes(string path)

变为

bool TryReadAllBytes(string path, out byte[] result)

但是这样不能提供用户更多的错误信息。如果我们想要显示更多的有帮助的异常信息给用户,可以返回一个通用的结果类OperationResult<TResult>

public class OperationResult<TResult>
{
private OperationResult ()
{
} public bool Success { get; private set; }
public TResult Result { get; private set; }
public string NonSuccessMessage { get; private set; }
public Exception Exception { get; private set; } public static OperationResult<TResult> CreateSuccessResult(TResult result)
{
return new OperationResult<TResult> { Success = true, Result = result};
} public static OperationResult<TResult> CreateFailure(string nonSuccessMessage)
{
return new OperationResult<TResult> { Success = false, NonSuccessMessage = nonSuccessMessage};
} public static OperationResult<TResult> CreateFailure(Exception ex)
{
return new OperationResult<TResult>
{
Success = false,
NonSuccessMessage = String.Format("{0}{1}{1}{2}", ex.Message, Environment.NewLine, ex.StackTrace),
Exception = ex
};
}
}

FileStorageService的ReadAllBytes 方法变为

public OperationResult<byte[]> TryReadAllBytes(string path)
{
try
{
var bytes = File.ReadAllBytes(path);
return OperationResult<byte[]>.CreateSuccessResult(bytes);
}
catch (FileNotFoundException fileNotFoundException)
{
return OperationResult<byte[]>.CreateFailure(fileNotFoundException);
}
}

调用代码:

var result = myStorageService.TryReadAllBytes(path);
if(result.Success)
{
// do something
}
else
{
Logger.Log(String.Format("Failed to read file from path, {0}: {1}", path, result.NonSuccessMessage));
}

原文:Error Handling in SOLID C# .NET – The Operation Result Approach

错误处理(Operation Result)方法的更多相关文章

  1. InnoDB: Operating system error number 87 in a file operation. 错误87的解决方法

    InnoDB: Operating system error number 87 in a file operation. 错误87的解决方法 140628  8:10:48 [Note] Plugi ...

  2. coreseek常见错误原因及解决方法

    coreseek常见错误原因及解决方法 Coreseek 中文全文检索引擎 Coreseek 是一款中文全文检索/搜索软件,以GPLv2许可协议开源发布,基于Sphinx研发并独立发布,专攻中文搜索和 ...

  3. android 真机调试出现错误 INSTALL_FAILED_INSUFFICIENT_STORAGE 的解决方法。

    关于这个神奇的 内存不够错误的通常解决方法,网上大把,建议大家在尝试过了网上的方法后再来尝试下我的这种方法. 编译工具: android studio 测试真机:米 2 调试的时候出现:INSTALL ...

  4. 无法打开物理文件xxx.mdf操作系统错误 5:“5(拒绝访问。)” (Microsoft SQL Server,错误: 5120)的解决方法

    无法打开物理文件xxx.mdf操作系统错误 5:“5(拒绝访问.)” (Microsoft SQL Server,错误: 5120)的解决方法   问题描述: 在附加数据库到sql server时,附 ...

  5. 错误:Unsupported major.minor version 51.0(jdk版本错误)的解决方法

    错误:Unsupported major.minor version 51.0(jdk版本错误)的解决方法 java.lang.UnsupportedClassVersionError: org/ap ...

  6. 批处理命令篇--配置免安装mysql 5.6.22, 以及1067错误的一个解决方法

    mysql 服务启动出现1067错误的一个解决方法: 当服务启动出现1067错误时,可查看“windows 事件查看器”,发现类似错误提示 Can't find messagefile 'F:\    ...

  7. IIS发布网站浏览之后看到的是文件目录 & Internal Server Error 处理程序“ExtensionlessUrlHandler-ISAPI-4.0_64bit”在其模块列表中有一个错误模块“IsapiModule” 解决方法 & App_global.asax.pduxejp_.dll”--“拒绝访问。 ”

    Q:IIS发布网站浏览之后看到的是文件目录 A:它出现了一个说到.NET4.0 更高框架什么的错误,所以我将 .NTE CRL版本由4.0改为2.0了,改为2.0后就出现了只能浏览文件目录了.改为4. ...

  8. ORA-04091错误原因与解决方法

    最近工作中写了一触发器报错:ORA-04091:table XX  is mutating, trigger/function may not see it. 下面通过官方文档及网友提供资料分析一下错 ...

  9. Eclipse进度条出现“Remote System Explorer Operation”解决方法

    Eclipse进度条出现“Remote System Explorer Operation”解决方法  

随机推荐

  1. (原创)Problem B: JRM的自动机

    Description JRM自称是自动机之鼻祖,今天他又发明了一个自动机.人称自动复读机,宣称比LGQ的复读机的性能好无数倍.这个复读机有很多功能,你可以教会他 如何回答一个问题,还可以询问他问题, ...

  2. 洛谷 P4297 [NOI2006]网络收费

    P4297 [NOI2006]网络收费 题目背景 noi2006 day1t1 题目描述 网络已经成为当今世界不可或缺的一部分.每天都有数以亿计的人使用网络进行学习.科研.娱乐等活动.然而,不可忽视的 ...

  3. P4841 城市规划 FFT+生成函数

    \(\color{#0066ff}{ 题目描述 }\) 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了. 刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使 ...

  4. P2117 小Z的矩阵

    题意: 给你一个初始01矩阵 三种操作 1.给一个x,把第x行01互换 2.给一个x,把第x列01互换 3.求$(\sum_{i=1}^n\sum_{j=1}^nf[i][j]*f[j][i])%2$ ...

  5. P1969 积木大赛

    题意:给你一段序列,一次操作:[l,r]内所有数+1 初始序列全为0 现在给你最后序列,问最少操作几次能达到这样的序列 蒟蒻表示秒想到------差分啊 每次差分必有一个+1,一个-1 把差分数组求出 ...

  6. iOS端VR视频播放(转自简书http://www.jianshu.com/p/1ee1a0d1d320)

    下面是我看了谷歌的一个VR在iOS端开发的文档写的一个demo. 第一步是需要用cocoaPods导入谷歌开发的一个第三方:CardboardSDK,怎么导入就不多说了,这里需要注意的一点是谷歌方面的 ...

  7. x0vncserver

    x0vncserver -display :0 -passwordfile ~/.vnc/passwd

  8. [Groovy]static typing

    一般想到Groovy是JVM上的动态语言,都不知道它还有Static Typeing的功能 import groovy.transform.TypeChecked void someMethod() ...

  9. 51Nod - 1242 斐波那契(快速幂)

    斐波那契数列的定义如下:   F(0) = 0 F(1) = 1 F(n) = F(n - 1) + F(n - 2) (n >= 2)   (1, 1, 2, 3, 5, 8, 13, 21, ...

  10. Zookeeper查看版本

    [root@ooccpp lib]# Zookeeper version: ---, built on // : GMT Clients: /[](queued=,recved=,sent=) /[] ...