Is there a name for this anti-pattern/code smell?

2019-03-23 05:39发布

Let me start by saying that I do not advocate this approach, but I saw it recently and I was wondering if there was a name for it I could use to point the guilty party to. So here goes.

Now you have a method, and you want to return a value. You also want to return an error code. Of course, exceptions are a much better choice, but for whatever reason you want an error code instead. Remember, I'm playing devil's advocate here. So you create a generic class, like this:

class FunctionResult<T>
{
    public T payload;
    public int result;
}

And then declare your functions like this:

FunctionResult<string> MyFunction()
{
    FunctionResult<string> result;
    //...

    return result;
}

One variation on this pattern is to use an enum for the error code instead of a string. Now, back to my question: is there a name for this, and if so what is it?

13条回答
ゆ 、 Hurt°
2楼-- · 2019-03-23 05:56

Well, it's not an antipattern. The C++ standard library makes use of this feature and .NET even offers a special FunctionResult class in the .NET framework. It's called Nullable. Yes, this isn't restricted to function results but it can be used for such cases and is actually very useful here. If .NET 1.0 had already had the Nullable class, it would certainly have been used for the NumberType.TryParse methods, instead of the out parameter.

查看更多
别忘想泡老子
3楼-- · 2019-03-23 05:58

If you don't want to use exceptions, the cleanest way to do it is to have the function return the error/success code and take either a reference or pointer argument that gets filled in with the result.

I would not call it an anti-pattern. It's a very well proven workable method that's often preferable to using exceptions.

查看更多
We Are One
4楼-- · 2019-03-23 06:00

Konrad is right, C# uses dual return values all the time. But I kind of like the TryParse, Dictionary.TryGetValue, etc. methods in C#.

int value;
if (int.TryParse("123", out value)) {
    // use value
}

instead of

int? value = int.TryParse("123");
if (value != null) {
    // use value
}

...mostly because the Nullable pattern does not scale to non-Value return types (i.e., class instances). This wouldn't work with Dictionary.TryGetValue(). And TryGetValue is both nicer than a KeyNotFoundException (no "first chance exceptions" constantly in the debugger, arguably more efficient), nicer than Java's practice of get() returning null (what if null values are expected), and more efficient than having to call ContainsKey() first.

But this is still a little bit screwy -- since this looks like C#, then it should be using an out parameter. All efficiency gains are probably lost by instantiating the class.

(Could be Java except for the "string" type being in lowercase. In Java of course you have to use a class to emulate dual return values.)

查看更多
仙女界的扛把子
5楼-- · 2019-03-23 06:02

I am not sure this is an anti-pattern. I have commonly seen this used instead of exceptions for performance reasons, or perhaps to make the fact that the method can fail more explicit. To me, it seems to be a personal preference rather than an anti-pattern.

查看更多
我只想做你的唯一
6楼-- · 2019-03-23 06:04

If you expect your method to fail occasionally, but don't consider that exceptional, I prefer this pattern as used in the .NET Framework:

bool TryMyFunction(out FunctionResult result){    

     //...    
     result = new FunctionResult();
}
查看更多
我只想做你的唯一
7楼-- · 2019-03-23 06:04

Debates about smells and anti-patterns remind me the "Survivor" TV shows, where you have various programming constructs trying to vote each other off the island. I'd prefer to see "construct X has such-and-so pros and cons", rather than a continually evolving list of edicts of what should and should not be done.

查看更多
登录 后发表回答