zancudos vinagre soportan repelentes ratones ratas que plantas para olores olor mosquitos moscas los gusta contra ahuyentar ahuyentan anti-patterns code-smell

anti-patterns - vinagre - que olor no soportan los ratones



¿Hay un nombre para este olor anti-patrón/código? (13)

Permítanme comenzar diciendo que no defiendo este enfoque, pero lo vi recientemente y me preguntaba si había un nombre que pudiera usar para señalar al culpable. Así que aquí va.

Ahora tiene un método y quiere devolver un valor. También quiere devolver un código de error. Por supuesto, las excepciones son una opción mucho mejor, pero en cualquier caso, desea un código de error. Recuerda, estoy jugando al abogado del diablo aquí. Entonces creas una clase genérica, como esta:

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

Y luego declara tus funciones de esta manera:

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

Una variación de este patrón es usar una enumeración para el código de error en lugar de una cadena. Ahora, volviendo a mi pregunta: ¿hay un nombre para esto, y si es así, qué es?


Bueno, no es un antipatrón. La biblioteca estándar de C ++ hace uso de esta característica y .NET incluso ofrece una clase especial FunctionResult en .NET framework. Se llama Nullable . Sí, esto no está restringido a los resultados de la función, pero se puede usar para tales casos y es realmente muy útil aquí. Si .NET 1.0 ya tenía la clase Nullable , sin duda se habría utilizado para los métodos NumberType.TryParse , en lugar del parámetro out .


En defensa de la designación antipatrón, este código se presta a ser utilizado de varias maneras:

  1. Objeto x = MyFunction (). Carga útil; (ignorando el resultado de la devolución, muy malo)
  2. int code = MyFunction (). result; (tirando la carga útil - puede estar bien si ese es el uso previsto).
  3. FunctionResult x = MyFunction (); // ... (un grupo de objetos adicionales de FunctionResult y un código adicional para revisarlos por todos lados)

Si necesita usar códigos de retorno, está bien. Pero luego usa los códigos de retorno. No trates de empacar una carga adicional con él. Para eso son los parámetros de ref y out (C #). Los tipos anulables pueden ser una excepción, pero solo porque hay azúcar extra horneado en el idioma para apoyarlo.

Si todavía no está de acuerdo con esta evaluación, DOWNVOTE esta respuesta (no toda la pregunta). Si crees que es un anti-patrón, entonces UPVÍTALO. Usaremos esta respuesta para ver qué piensa la comunidad.


Este enfoque es en realidad mucho mejor que algunos otros que he visto. Algunas funciones en C, por ejemplo, cuando encuentran un error, vuelven y parecen tener éxito. La única manera de decir que fallaron es llamar a una función que recibirá el último error.

Pasé horas intentando depurar el código del semáforo en mi MacBook antes de que finalmente descubriera que sem_init no funciona en OSX. Se compiló sin error y se ejecutó sin causar ningún error; sin embargo, el semáforo no funcionó y no pude entender por qué. Lamento a las personas que portan una aplicación que usa semáforos POSIX a OSX y deben lidiar con problemas de contención de recursos que ya han sido depurados.


Estoy de acuerdo con aquellos que dicen que esto no es un antipatrón. Es un patrón perfectamente válido en ciertos contextos. Las excepciones son para situaciones excepcionales , los valores de retorno (como en su ejemplo) deben usarse en situaciones esperadas. Algunos dominios esperan resultados válidos e inválidos de las clases, y ninguno de estos debe modelarse como excepciones.

Por ejemplo, dada una cantidad X de gas, ¿puede un automóvil llegar de A a B y, de ser así, cuánto gas queda? Ese tipo de pregunta es ideal para la estructura de datos que proporcionó. No se puede hacer el viaje de A a B, por lo tanto, no se debe usar una excepción.


Estoy de acuerdo en que esto no es específicamente un antipatrón. Puede ser un olor dependiendo del uso. Hay razones por las cuales uno no querría usar excepciones (por ejemplo, los errores que se devuelven no son ''excepcionales'', para empezar).

Hay casos en los que desea que un servicio devuelva un modelo común para sus resultados, incluidos errores y buenos valores. Esto podría estar envuelto por una interacción de servicio de bajo nivel que traduce el resultado en una estructura de excepción u otra estructura de error, pero a nivel del servicio, permite que el servicio devuelva un resultado y un código de estado sin tener que definir alguna estructura de excepción que pueda tienen que traducirse a través de un límite remoto.

Este código también puede no ser necesariamente un error: considere una respuesta HTTP, que consiste en una gran cantidad de datos diferentes, incluido un código de estado, junto con el cuerpo de la respuesta.


Konrad tiene razón, C # usa valores de doble retorno todo el tiempo. Pero me gustan los métodos TryParse, Dictionary.TryGetValue, etc. en C #.

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

en lugar de

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

... principalmente porque el patrón Nullable no escala a tipos de devolución sin valor (es decir, instancias de clase). Esto no funcionaría con Dictionary.TryGetValue (). Y TryGetValue es más agradable que KeyNotFoundException (no hay "excepciones de primera oportunidad" constantemente en el depurador, podría decirse que más eficiente), mejor que la práctica de Java de get () devolver nulo (qué ocurre si se esperan valores nulos) y más eficiente que tener que llame a ContainsKey () primero.

Pero esto todavía es un poco complicado, ya que se ve como C #, entonces debería estar usando un parámetro de salida. Todos los aumentos de eficiencia probablemente se pierden al crear una instancia de la clase.

(Podría ser Java, excepto que el tipo de "cadena" está en minúsculas. En Java, por supuesto, debe usar una clase para emular valores de retorno duales).


No estoy seguro de que esto sea un antipatrón. Comúnmente he visto esto usado en lugar de excepciones por motivos de rendimiento, o quizás para hacer que el hecho de que el método pueda fallar sea más explícito. Para mí, parece ser una preferencia personal en lugar de un antipatrón.


Normalmente paso la carga útil como referencia (no const) y el código de error como valor de retorno.

Soy un desarrollador de juegos, desterremos excepciones


Qué tal el patrón "No se puede decidir si esto es un error o no". Parece que si realmente tuvieras una excepción pero quisieras devolver un resultado parcial, envolverías el resultado en la excepción.


Si espera que su método falle ocasionalmente, pero no lo considere excepcional, prefiero este patrón como se usa en .NET Framework:

bool TryMyFunction(out FunctionResult result){ //... result = new FunctionResult(); }


Si no desea usar excepciones, la forma más limpia de hacerlo es hacer que la función devuelva el código de error / éxito y tome un argumento de referencia o de puntero que se complete con el resultado.

Yo no lo llamaría antipatrón. Es un método viable muy bien probado que a menudo es preferible al uso de excepciones.



Los debates sobre olores y antipatrones me recuerdan a los programas de televisión "Survivor", donde tienes varios constructos de programación tratando de votar unos a otros fuera de la isla. Preferiría ver que "constructo X tiene pros y contras de tal y tal", en lugar de una lista en constante evolución de edictos de lo que debe y no debe hacerse.