Допустим, у меня есть следующий сценарий:
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 имеет пустой импл.из addSomeSpecialThings.Также этот пример очень простой.Например, в методе может быть больше различий, поэтому будет нелегко извлечь ту же функциональность.
Мои решения основаны на наследовании, может быть, было бы лучше сделать это с помощью композиции.Я также подумал, что это, вероятно, кандидат на стратегию.
Ну, каков наилучший подход к такой проблеме?Заранее спасибо за любую помощь.
Куку.