oop - sentencia - Programación If-less(básicamente sin condicionales)
que significa != en python (6)
He tenido un colega que me dijo que una vez trabajó para una compañía que tenía como política no tener condicionales (declaraciones "si" y "cambiar") en el código y que dejaran que todas las decisiones en el código se hicieran usando polimorfismo y (supongo) algunos otros principios OO.
Creo que su colega malentendió algo o usó las palabras incorrectas para explicarlo. Y no puedes evitar completamente las declaraciones condicionales.
Hay algo que decir: la proliferación de sentencias if dentro de OOP puede ser un síntoma de mala programación. Un ejemplo:
No use si para verificar el valor de retorno de la función como una antigua programación estilo C:
int ret = some_func();
if (ret != null)
//do something
Esto era típico en el código C, pero con OOP debe usar la excepción:
try{
do_something();
}catch(Exception e){
e.printStackTrace(); //why I was not able to do something
handle(e); //there is something else I could do to handle the occurred error
}
A veces, si la proliferación de declaraciones está relacionada con un diseño incorrecto. Considere el siguiente ejemplo en Java:
BaseClass base;
if (base instanceof DerivedClassOneFromBase){
DerivedClassOneFromBase d = (DerivedClassOneFromBase)base;
d.methodOne();
}else if (base instanceof DerivedClassOneFromBase){
DerivedClassTwoFromBase d = (DerivedClassTwoFromBase)base;
d.methodTwo();
}
Este es otro ejemplo de malas declaraciones if, probablemente relacionadas con un mal diseño. Si los dos objetos derivados tuvieran un método común definido en su clase base BaseClass, usted podría haber llamado a ese método en lugar de verificar su tipo concreto y emitirlos:
base.commonMethod();
He tenido un colega que me dijo que una vez trabajó para una compañía que tenía como política no tener condicionales (declaraciones "si" y "cambiar") en el código y que dejaran que todas las decisiones en el código se hicieran usando polimorfismo y (supongo) algunos otros principios OO.
Entiendo el razonamiento detrás de esto, de tener un código que es más SECO y más fácil de actualizar, pero estoy buscando una explicación más profunda de este concepto. O tal vez es parte de un enfoque de diseño más general.
Si alguien tiene algún recurso para esto o estaría dispuesto a explicar o incluso tiene algunos términos más relacionados con esto que pueda utilizar para encontrar más respuestas, estaría muy agradecido.
Encontré una pregunta en SO que estaba relacionada, pero no estoy familiarizado con C ++, así que no entiendo muchas de las respuestas allí.
(No soy un gurú de OO, pero puedo hacerlo)
Soy más hábil en PHP, y después de eso Python, así que prefiero información que use esos idiomas.
Actualización: Le pediré a mi colega más información sobre lo que quiso decir exactamente.
Actualización 2015: después de algunos años más de experiencia en programación, veo ahora que el objetivo de esta política fue probablemente evitar que los programadores agreguen funcionalidades de forma fortuita simplemente agregando condicionales (declaraciones if) en ciertos lugares. Una mejor forma de extender el software es usar el "principio abierto / cerrado" donde el software se extiende mediante el uso de herencia y polimorfismo. Dudo mucho si la política fue muy estricta con todos los condicionales, ya que es un poco difícil ir completamente sin ellos.
A veces, los condicionales dentro de los métodos son malos, ya que son un signo de que solo está realizando múltiples funciones o métodos de varios tipos en el único método.
Si tiene una clase llamada Automóvil y subclases como Coche y Bicicleta, y un método como:
drive(Automobile a)
if (a.isCar)
// do stuff
else if (a.isBike)
// do stuff
usted es más que nada haciendo algo mal. Incluso si no se trata de un interruptor basado en el tipo, a menudo puede estar equivocado. Si el método realiza múltiples funciones dependiendo de alguna variable, a menudo intenta hacer más de una cosa y probablemente debería separarse en múltiples métodos.
Por ejemplo:
save(Car c)
if (c is new)
// do some stuff
else if (c is old)
// do some stuff
podría dividirse en guardar y actualizar, ya que son dos funciones diferentes. Aunque sí depende.
Prohibir completamente si las declaraciones serían tontas, ya que tienen muchos casos de uso válidos.
Después de algunos años de programación, vuelvo a mi propia pregunta, cuyo contexto ahora entiendo un poco mejor.
Hay una buena charla de Sandi Metz donde ella refactoriza una bola realmente peluda de declaraciones if a algo menos peludo: https://www.youtube.com/watch?v=8bZh5LMaSmE
Evitar condicionales no significa necesariamente que deba hacerlo por polimorfismo o herencia, tome por ejemplo:
Tienes 3 carpetas diferentes para almacenar imágenes cargadas, videos cargados y archivos PDF cargados
Puedes escribir código como:
uploadMedia(mediaType){
if(mediaType == images){
uploadTo("myProject/images");
}else if(mediaType == videos){
upoloadTo("myProject/videos);
}else if(mediaType == pdf){
uploadTo("myProject/pdf");
}
}
Otra alternativa que las personas pueden usar es la caja del interruptor:
uploadMedia(mediaType){
switch(mediaType){
case : images
uploadTo("myProject/images");
break;
case : videos
uploadTo("myProject/videos");
break;
case : pdf
uploadTo("myProject/pdf");
break;
}
}
Pero luego puedes evitar totalmente el enunciado condicional usando algo como dictionary / hashmap / json (Dependiendo de lo que trabajes):
Por ejemplo :
HashMap<String,String> mediaMap = new HashMap<>();
mediaMap.put("images","myProject/images");
mediaMap.put("videos","myProject/videos");
mediaMap.put("pdf","myProject/pdf");
//mediaType can be images/videos/pdf same as keys of mediaMap
uploadMedia(mediaType){
uploadTo(mediaMap.get(mediaType));
}
Esto es una especie de pseudo código, por lo que podría haber errores de sintaxis, pero en general este concepto también es útil para evitar condicionales. También se puede reducir la línea de código.
Hay algunos recursos en el sitio Anti-IF Campaign , como este artículo .
Creo que es una cuestión de grado. Los condicionales no siempre son malos, pero pueden ser (y con frecuencia son) abusados.
Pensamientos adicionales (un día después)
Refactorización: mejorar el diseño del código existente es una buena referencia sobre este tema (y muchos otros). Cubre Reemplazar condicional con polimorfismo . También hay uno nuevo, Reemplazar condicional con Visitante , en el sitio web.
Valoro la simplicidad y la responsabilidad única sobre la eliminación de todas las declaraciones if
. Estos tres objetivos a menudo coinciden. Las herramientas de análisis estático que admiten la métrica de complejidad ciclomática pueden señalar rápidamente el código con condicionales anidados o en serie. Las sentencias if
pueden permanecer después de la refactorización, pero se pueden dividir en métodos más pequeños y / o múltiples clases.
Actualización: Michael Feathers escribió un artículo sobre Programación incondicional .
Este es un tema popular: ¡Phil Haack en Death to the IF statement !
Leí la publicación que vinculó y parece que en su mayoría hablaban de eliminar la necesidad de condicionales dentro de una clase , para no confundirla con todo el código en general. La idea es que si necesita verificar el estado de un objeto (usando un condicional) para determinar si tiene cierta funcionalidad, entonces en realidad tiene dos objetos (uno que admite la funcionalidad y otro que no) y debería definirlos como dos clases relacionadas en su lugar.