Intento seguir el Principio de responsabilidad única (SRP) y también omitir las repeticiones de código. Sin embargo, a menudo hay lugares donde hay repeticiones de código que no son más que bloques de invocaciones de código que son resistentes a extraerlas en un método con un nombre al menos significativo:
DoAction1();
DoAction2();
if (value)
DoAction3();
DoAction4();
¿Cuál es la mejor manera de extraer dicho código en un método y cómo nombrarlo?
void MethodThatDoAction1ThenAction2AndAction3IfValueAndThenAction4()
. Prefiero ver más significado en:CodeBlock1()
.AbstractInterruptibleBatchPreparedStatementSetter
que es solo un poco más pequeño que tu método.Respuestas:
Creo que es simplemente una cuestión de nombrar correctamente el método extraído. Me temo que no hay una solución universal y tendrá que hacerlo caso por caso. Si está repitiendo exactamente el mismo fragmento de código en más de 1 lugar, seguramente habrá un significado para sus acciones y tendrá que buscar mucho (puede discutirse) para encontrar ese significado y darle un nombre.
Si te sirve de consuelo, el ganador de primavera para los nombres de clase largos es el
AbstractInterruptibleBatchPreparedStatementSetter
que tiene 49 caracteres.fuente
En realidad, está sufriendo la tarea más difícil que debe realizar un programador : Naming Things . Perdón por una respuesta tan madura pero no pude resistirme. Puede encontrar que muchas personas sufren de esto , incluso en Internet puede encontrar este tipo de ensayo .
Ahora, si su código repetitivo es todo el resultado de un trabajo y esos métodos no están siendo utilizados por otros métodos, entonces son simplemente métodos de Ayuda y luego el método resultante se puede nombrar como
doXXX
omakeXXX
... Creo que entiende el punto.Como dijo Chandranshu "Si estás repitiendo [...] este significado y le das un nombre". es al grano y apropiado.
Foto cortesía: CodeChef Facebook Page Photo
fuente
Creo que está llevando el principio de repetición del código demasiado lejos. Piense en el punto de evitar la repetición de código. El punto es reducir la cantidad de código que debe verificarse cuando hay un cambio en la lógica, y aumentar la comprensión al factorizar bloques obviamente de intención similar.
Las desventajas de la factorización para evitar la repetición son que si uno de los bloques compartidos tiene que cambiar, ahora necesita una herencia aún más compleja o un cambio entre la implementación estándar y la no estándar.
Por lo tanto, sopese cuidadosamente la posibilidad de que la lógica de incluso uno de estos bloques cambie sin los otros contra los beneficios de comprensión obtenidos al factorizar esta comunidad. Si una implementación puede separarse de las demás, es mejor que simplemente repita el código.
Mientras mantiene este código repetido, a medida que se vuelve más complejo y el dominio de su problema se vuelve más definido, puede encontrar más apropiado factorizar las secciones repetidas, ahora más complejas, pero también más definidas.
Por lo general, trato de mantener la uniformidad del editor de texto durante un tiempo hasta que puedo ver si vale la pena factorizar algo que parece ser repetitivo. Simplemente mantengo la repetición, pero mantengo mi ojo hacia el futuro de ese bloque al mantenerlo textualmente fácil de combinar más tarde.
Gran parte del tiempo, la igualdad y la posible factorización comienzan a disiparse, como reglas comerciales reales, caprichosas y una lógica altamente dependiente, a menudo arbitraria; como lidiar con las rarezas de varias implementaciones de bases de datos comunes (ANSI_NULLS o algo así viene a la mente) se agregan; obligando a lo que parecía una lógica pura a un desorden retorcido, tratando de proporcionar una lógica de decisión razonable y defendible cuando se enfrenta con el desorden del estado de la industria.
Me parece que si la gente tratara de descifrar lo que está tratando de factorizar, tendríamos una biblioteca completa de construcciones sin valor como Do1Then2If2False Do1IfTrueDo2.
Tiene que ser más complejo y más claro que el bloque no va a cambiar para justificar su factorización.
Es software . Puede regresar y editar un par de bloques que son iguales en este momento. Tomará 5 minutos. Y puede ahorrar horas de factorización desperdiciada, y luego horas más de herencia desperdiciada y desarrollo de conmutación, simplemente dejándolo y asegurándose de tener un buen teclado anti-RSI.
fuente
Si realmente está siguiendo el Principio de responsabilidad única, entonces este bloque de código debe tener un propósito específico, ¿verdad? De lo contrario, estos métodos estarían en clases separadas.
Entonces, ¿cuál es el propósito de este bloque de código? Determina eso y deberías ser capaz de encontrar un nombre.
Si aún no puede averiguar el nombre de esta cosa, entonces tal vez estos métodos en realidad no estén juntos. Es decir, este bloque de clase / código tiene más de una responsabilidad. En ese caso, refactorizar para dividir las tareas puede revelar un mejor nombre revelador.
fuente
He tenido una situación que puede ser similar a la tuya:
Hay una clase que define la funcionalidad del objeto que representa:
Luego hay una clase que define los flujos de trabajo para operaciones de alto nivel que realiza el objeto:
Si se encuentra en una situación similar, identifique qué representan sus clases (en este caso, funcionalidad / flujos de trabajo) y luego nombre los métodos en consecuencia.
Descargo de responsabilidad: los nombres de clase utilizados en este ejemplo son muy inexactos, pero los nombres de los métodos dan una pista. Discreción aconsejada.
fuente