Допустим, у меня есть следующий сценарий:
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();
}
}
И еще один класс, который должен выполнить аналогичную задачу:
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();
}
}
Что было бы хорошей стратегией, чтобы избежать дублирования кода? До сих пор я пришел к выводу, что класс B, который имеет функциональность подмножества A и поэтому должен распространяться от класса A, и те же задачи должны быть реорганизованы в защищенные методы (при условии, что они находятся в одном пакете). Вот как это выглядит:
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;
}
}
И класс B:
public class B extends A {
public String createString(final String value){
final StringBuffer sb = createTheFirstPart(value);
createTheLastPart(sb);
return sb.toString();
}
}
Другим возможным решением могло бы быть что-то вроде этого:
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");
}
}
}
и класс 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
}
}
Очевидно, это не так хорошо, потому что B имеет пустой имп. of addSomeSpecialThings. Также этот пример является очень простым. Например, может быть больше различий в методе, поэтому было бы нелегко извлечь одну и ту же функциональность.
Мои решения касаются наследования, возможно, было бы лучше сделать это с композицией. Я также подумал, что это, вероятно, является препятствием для стратегии.
Хорошо, какой лучший подход к такой проблеме? Заранее благодарим за любую помощь.
Куку.