Digamos que tengo el siguiente escenario:buena estrategia para evitar el código duplicado
public class A {
public String createString(final String value){
if (value == null){
throw new NullPointerException("value must NOT be null.");
}
final StringBuffer sb = new StringBuffer();
sb.append("A");
sb.append("B");
sb.append("C");
if (value.length() > 3){
sb.append("D");
sb.append("E");
}
sb.append("Z");
return sb.toString();
}
}
Y otra clase que debe hacer una tarea similar:
public class B {
public String createString(final String value){
if (value == null){
throw new NullPointerException("value must NOT be null.");
}
final StringBuffer sb = new StringBuffer();
sb.append("A");
sb.append("B");
sb.append("C");
sb.append("Z");
return sb.toString();
}
}
¿Cuál sería una buena estrategia para evitar la código duplicado? Lo que se me ocurrió hasta ahora es que la clase B que tiene una funcionalidad subconjunto de A y que, por lo tanto, debe extenderse desde la clase A y las mismas tareas deben refactorizarse en métodos protegidos (suponiendo que estén en el mismo paquete). Esto es lo que se vería así:
public class A {
public String createString(final String value){
final StringBuffer sb = createTheFirstPart(value);
if (value.length() > 3){
sb.append("D");
sb.append("E");
}
createTheLastPart(sb);
return sb.toString();
}
protected void createTheLastPart(final StringBuffer sb) {
sb.append("Z");
}
protected StringBuffer createTheFirstPart(final String value) {
if (value == null){
throw new NullPointerException("value must NOT be null.");
}
final StringBuffer sb = new StringBuffer();
sb.append("A");
sb.append("B");
sb.append("C");
return sb;
}
}
Y la clase B:
public class B extends A {
public String createString(final String value){
final StringBuffer sb = createTheFirstPart(value);
createTheLastPart(sb);
return sb.toString();
}
}
Otra posible solución sería algo como esto:
public class A {
public String createString(final String value){
if (value == null){
throw new NullPointerException("value must NOT be null.");
}
final StringBuffer sb = new StringBuffer();
sb.append("A");
sb.append("B");
sb.append("C");
addSomeSpecialThings(value, sb);
sb.append("Z");
return sb.toString();
}
protected void addSomeSpecialThings(final String value, final StringBuffer sb) {
if (value.length() > 3){
sb.append("D");
sb.append("E");
}
}
}
y la clase B:
public class B extends A {
public String createString(final String value){
return super.createString(value);
}
protected void addSomeSpecialThings(final String value, final StringBuffer sb) {
// do nothing
}
}
Obviamente Thi s no es tan bueno porque B tiene una impl vacía. de addSomeSpecialThings. También este ejemplo es muy simple. Por ejemplo, podría haber más diferencia dentro del método, por lo que no sería tan fácil extraer la misma funcionalidad.
Mis soluciones son todos acerca de la herencia quizá también sería mejor hacer esto con la composición. También pensé que esto es probablemente un canidate para el patrón de estrategia.
bien cuál es el mejor enfoque para este tipo de problema? Gracias de antemano por cualquier ayuda.
kuku.
Mi problema con esto es la impl vacía. que trato de evitar – kukudas
@kukudas: Luego haga que el método esté vacío en la superclase y omítalo en B. – thejh