Tengo una pregunta sobre duplicación de código y refactorización, espero que no sea demasiado general. Supongamos que tiene un fragmento de código bastante pequeño (~ 5 líneas) que es una secuencia de invocaciones de función que no es un nivel muy bajo. Este código se repite en varios lugares, por lo que probablemente sea una buena idea extraer un método aquí. Sin embargo, en este ejemplo particular, esta nueva función sufriría de baja cohesión (que se manifiesta, entre otros, por tener dificultades para encontrar un buen nombre para la función). La razón de esto es probablemente porque este código repetido es solo una parte de un algoritmo más grande, y es difícil dividirlo en pasos bien nombrados.¿SECAR o no SECAR? Al evitar la duplicación de código y mantener la cohesión
¿Qué sugerirías en tal escenario?
Editar:
quería mantener la cuestión en un plano general, para que más gente puede encontrar potencialmente útil, pero es evidente que lo mejor sería que lo respalde con algún ejemplo de código. El ejemplo podría no ser el mejor de todos (huele en bastantes maneras), pero espero que hace su trabajo:
class SocketAction {
private static class AlwaysCreateSessionLoginHandler extends LoginHandler {
@Override
protected void onLoginCorrect(SocketAction socketAction) throws IllegalAccessException, IOException {
Server.checkAllowedDeviceCount(socketAction._sess.getDeviceID());
socketAction.registerSession();
socketAction._sess.runApplication();
}
}
private static class AutoConnectAnyDeviceLoginHandler extends LoginHandler {
@Override
protected void onLoginCorrect(SocketAction socketAction) throws IllegalAccessException, IOException {
if (Server.isUserRegistered(socketAction._sess.getUserLogin())) {
Log.logSysInfo("Session autoconnect - acquiring list of action threads...");
String[] sa = Server.getSessionList(socketAction._sess.getUserID());
Log.logSysInfo("Session autoconnect - list of action threads acquired.");
for (int i = 0; i < sa.length; i += 7) {
socketAction.abandonCommThreads();
Server.attachSocketToSession(sa[i + 1], socketAction._commSendThread.getSock());
return;
}
}
Server.checkAllowedDeviceCount(socketAction._sess.getDeviceID());
socketAction.registerSession();
socketAction._sess.runApplication();
}
}
private static class OnlyNewSessionLoginHandler extends LoginHandler {
@Override
protected void onLoginCorrect(SocketAction socketAction) throws IllegalAccessException, IOException {
socketAction.killOldSessionsForUser();
Server.checkAllowedDeviceCount(socketAction._sess.getDeviceID());
socketAction.registerSession();
socketAction._sess.runApplication();
}
}
}
Estoy tratando de encontrar una pieza compacta de código para respaldar mi pregunta, pero la base de código que en cierto modo me desafié a refactorizar, parece ser un desastre que es difícil aislar el problema y probablemente sería difícil pegar nada sin entrar en una descripción larga y aburrida. Creo que lo definiste con la sugerencia de que "debería haber una abstracción viable en alguna parte". Es una sensación tan fuerte, que sigo mirando el código, negándome a dejarlo ir. ¡Porque simplemente * sé * hay una manera mejor de expresar la idea completa que estas cosas de espaguetis! – lukem00
He agregado algunos ejemplos de código. ¿Desea ampliar la descripción del enfoque general con algunos consejos y sugerencias específicos para obtener una mejor ilustración? – lukem00
@ lukem00: No sé, ¿quizás esas 3 líneas comunes podrían convertirse en un método de 'SocketAction', también llamado' onLoginCorrect'? Es decir, se espera que cada 'LoginHandler' haga lo suyo y luego delegue en' SocketAction', que hace esas cosas de la sesión. –