
Is there a name for this anti-pattern/code smell?首先,我说我不主张采用这种方法,但是最近我看到了这种方法,我想知道是否有一个名字可以用来指认有罪的政党。 所以去。 现在您有了一个方法,并且想要返回一个值。 您还想返回一个错误代码。 当然,异常是更好的选择,但是无论出于何种原因,您都希望使用错误代码。 记住,我在这里扮演恶魔的拥护者。 因此,您将创建一个通用类,如下所示:
然后像这样声明你的函数:
此模式的一种变体是对错误代码使用枚举而不是字符串。 现在,回到我的问题:对此有一个名称吗? 我同意这不是专门的反模式。根据使用情况,可能会有异味。有一些原因导致人们实际上不希望使用异常(例如,对于初学者来说,返回的错误不是" exception")。 在某些情况下,您希望服务为其结果返回一个通用模型,包括错误和良好值。这可能被低级服务交互所包装,该服务交互将结果转换为异常或其他错误结构,但是在服务级别,它使服务可以返回结果和状态代码,而不必定义可能会导致异常的异常结构。必须跨远程边界进行翻译。 该代码也不一定是错误:考虑一个HTTP响应,该响应由许多不同的数据(包括状态码)以及响应主体组成。 它被称为"用异常替换错误代码"
好吧,这不是反模式。 C ++标准库利用了此功能,.NET甚至在.NET框架中提供了一个特殊的 我通常将有效负载作为(非const)引用传递,并将错误代码作为返回值传递。 我是游戏开发人员,我们排除了例外情况 Konrad是正确的,C#始终使用双返回值。但是我有点像C#中的TryParse,Dictionary.TryGetValue等方法。
代替
...主要是因为Nullable模式无法缩放为非Value返回类型(即类实例)。这不适用于Dictionary.TryGetValue()。而且TryGetValue不仅比KeyNotFoundException(在调试器中始终没有"第一次机会异常",可以说效率更高)要好,比Java的get()返回null(如果期望null值会怎样)的做法还好,并且比必须这样做要更有效。首先调用ContainsKey()。 但这仍然有些棘手-因为它看起来像C#,所以应该使用out参数。实例化类可能会损失所有效率提高。 (除了" string"类型为小写字母外,它可以是Java。在Java中,您当然必须使用一个类来模拟双返回值。) 我不确定这是否是反模式。出于性能原因,我经常看到使用此方法而不是使用异常,或者可能是为了使该方法失败的事实更加明确。在我看来,这似乎是个人喜好而不是反模式。 我同意那些说这不是反模式的人的观点。在某些情况下,这是一种完全有效的模式。在特殊情况下例外,应在预期情况下使用返回值(如您的示例中所示)。一些域期望类产生有效和无效的结果,并且都不应该将它们建模为异常。 例如,给定X倍的汽油量,一辆汽车可以从A到B行驶吗?如果有,还剩下多少汽油?对于您提供的数据结构,这种问题是理想的。预计无法进行从A到B的旅行,因此不应使用异常。 实际上,这种方法比我所见过的其他方法要好得多。例如,C语言中的某些函数在遇到错误时会返回并似乎成功。告诉他们失败的唯一方法是调用将获得最新错误的函数。 我花了数小时尝试在MacBook上调试信号灯代码,然后才终于发现sem_init在OSX上不起作用!它编译时没有错误,并且在运行时没有引起任何错误-但是该信号灯不起作用,我不知道为什么。我很感激那些将使用POSIX信号的应用程序移植到OSX并必须处理已经调试的资源争用问题的人们。 关于气味和反模式的辩论让我想起了"幸存者"电视节目,那里有各种各样的编程结构试图在岛上互相投票。我宁愿看到" construct X具有某种优缺点",而不是不断发展的关于应该做什么和不应该做什么的法令列表。 如果您希望您的方法偶尔会失败,但又不认为这种例外,我更喜欢在.NET Framework中使用的这种模式:
如果您不想使用异常,则最干净的方法是让函数返回错误/成功代码,并采用填充了结果的引用或指针参数。 我不会称其为反模式。这是一种行之有效的可行方法,通常比使用异常更好。 "无法确定这是否是错误"模式如何呢?好像您确实有异常,但想返回部分结果,则将结果包装在异常中。 为了反模式的指定,该代码可以通过以下几种方式使用: 如果您需要使用返回码,那很好。但是,然后使用返回码。不要尝试在其中打包额外的负载。这就是ref和out参数(C#)的目的。可空类型可能是一个例外,但这仅是因为在语言中还增加了额外的糖来支持它。 如果您仍然不同意此评估,请对这个答案(不是整个问题)进行投票。如果您确实认为这是一种反模式,请对其进行投票。我们将使用此答案来查看社区的想法。 |