¿Qué crees que hace que la gente se impaciente más cuando se hacen cargo del código heredado? ¿UML extremadamente complejo? No me parece. Mi respuesta es, si con más de dos casos más, o cambiar con más de dos casos. Pero, ¿es normal usar muchos if else y cambiar entre mayúsculas y minúsculas en el código? ¡equivocado! La mayoría de los casos if else y switch con más de dos ramas no deberían aparecer en forma codificada.
¿De dónde vienen las ramas complejas?
En primer lugar, la primera pregunta que queremos discutir es por qué suele haber tantas ramas complejas en el código heredado. Estas ramas complejas a menudo no existen en la primera versión del código. Suponiendo que el diseñador todavía tenga algo de experiencia, debería prever áreas que podrían necesitar ser ampliadas en el futuro y reservar interfaces abstractas .
Sin embargo, después de que el código pasa por varias iteraciones, especialmente después de varios ajustes en los detalles de los requisitos, aparecerán ramas complejas. Los ajustes detallados a los requisitos a menudo no se reflejan en UML, sino que se reflejan directamente en el código. Por ejemplo, los mensajes se dividieron originalmente en dos categorías: mensajes de chat y mensajes del sistema. Durante el diseño, estos se diseñaron naturalmente como dos subcategorías de la categoría de mensajes. Pero un día los requisitos se ajustan en detalle. Algunos de los mensajes del sistema son importantes y sus títulos deberían mostrarse en rojo. En este momento, los programadores suelen realizar las siguientes modificaciones:
Agregue un atributo importante a la clase de mensaje del sistema
Agregue una rama sobre el atributo importante en el método de renderizado correspondiente para controlar el color del título. ¿Por qué el programador haría tal cambio? Tal vez sea porque no se dio cuenta de que debería ser abstracto. Debido a que el requisito dice "algunos de los mensajes del sistema son importantes", para los programadores que han recibido más capacitación en lenguajes de programación imperativos, lo primero que pueden pensar es en el bit de bandera: un bit de bandera puede distinguir entre los importantes y los que no lo son. . importante. No esperaba que este requisito pudiera interpretarse de otra manera: "Los mensajes del sistema se dividen en dos categorías: importantes y sin importancia". Al interpretarlo de esta manera, sabía que los mensajes del sistema debían abstraerse.
Es posible, por supuesto, que el programador sepa que la abstracción es posible, pero por alguna razón decida no hacerlo. Una situación muy común es que alguien obligue a los programadores a sacrificar la calidad del código a cambio de la velocidad del progreso del proyecto; agregar una propiedad y una rama es mucho más simple que la refactorización abstracta. Si desea hacer 10 de esta forma Modificar, ¿es más rápido hacer 10? ¿ramas o 10 abstracciones? La diferencia es obvia.
Por supuesto, si hay demasiados, algunas personas inteligentes se levantarán y dirán: "¿Por qué no lo cambiamos por una caja de interruptor?" En algunos casos, esto puede mejorar la legibilidad del código, suponiendo que cada rama sea mutuamente excluyente. Pero cuando aumenta el número de casos de cambio, el código también se volverá ilegible.
¿Cuáles son las desventajas de las sucursales complejas?
¿Cuáles son las desventajas de las sucursales complejas? Permítanme tomar como ejemplo una sección del código antiguo de la versión web de Baidu Hi.
cambiar (json.resultado) {
caso "bien":
cambiar (json.comando) {
caso "mensaje":
caso "mensaje del sistema":
si (json.content.from == ""
&& json.content.content == "pateado") {
/* desconectar */
} else if (json.command == "mensaje del sistema"
|| json.content.tipo == "sysmsg") {
/* renderizar mensaje del sistema */
} demás {
/* renderizar mensaje de chat */
}
romper;
}
romper;