假设我有以下情况:
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有空的impl。 addSomeSpecialThings。 这个例子也很简单。例如,方法中可能存在更多差异,因此提取相同的功能并不容易。
我的解决方案都是关于继承的,也许用组合做这件事也会更好。我还认为这可能是战略模式的一个因素。
那么这种问题的最佳方法是什么?提前感谢您的帮助。
裤裤。
答案 0 :(得分:10)
我会将共享代码放在A和B的超类中:
public abstract class SomeName {
public final 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 abstract void addSomeSpecialThings(final String value,
final StringBuffer sb);
}
然后B看起来像这样:
public class B extends SomeName {
protected void addSomeSpecialThings(final String value,
final StringBuffer sb) {}
}
这将是A:
public class A extends SomeName {
protected void addSomeSpecialThings(final String value, final StringBuffer sb) {
if (value.length() > 3){
sb.append("D");
sb.append("E");
}
}
}
答案 1 :(得分:3)
描述的情况相当简单。我认为继承在这里是可以的,但我建议创建一个带有空实现的addSomeSpecialThings的基类,然后继承两个类,A和B,并覆盖该方法。
策略模式是合适的,但不是在这种简单的情况下。对于实现模式所需的开销,有两种情况太少了。
答案 2 :(得分:1)
这种简单的代码没有任何重要因素,但会牺牲可读性。组合与继承选择只会与更现实的例子有关,并且也更加明显。