Java 避免重复代码的好策略
假设我有以下场景:Java 避免重复代码的好策略,java,oop,design-patterns,Java,Oop,Design Patterns,假设我有以下场景: 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(); s
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。增加一些特别的东西。
这个例子也很简单。例如,方法中可能存在更多差异,因此提取相同的功能就不那么容易了
我的解决方案都是关于继承的,也许用组合来实现这一点会更好。我还认为这可能是战略模式的一个重要方面
那么,解决此类问题的最佳方法是什么?提前感谢您的帮助
kuku.我将把共享代码放在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) {}
}
这将是一个:
public class A extends SomeName {
protected void addSomeSpecialThings(final String value, final StringBuffer sb) {
if (value.length() > 3){
sb.append("D");
sb.append("E");
}
}
}
所描述的情况相当简单。我认为继承在这里是可以的,但我建议创建一个带有空实现的addSomeSpecialThings的基类,然后继承两个类a和B,并重写该方法
战略模式是合适的,但不是在这样简单的情况下。有两种情况对于实现模式所需的开销来说太少了。以牺牲可读性为代价在这样简单的代码中进行分解是没有意义的。组合与继承的选择只会与更现实的例子有关,而且也更明显。hm。。是的,这是一个非常简单的例子,但我认为即使在这里也应该避免重复代码。当我必须决定组合与继承时,我只会问一个基本问题:这真的是一种“是-是”关系吗。大多数情况下,答案是显而易见的。所有重复都是从简单开始的,然后当开发人员找这样的借口,而不是遵循适当的工程实践时,它就会变成一个复杂的混乱。这是一个很好的建议,谢谢。但是我不喜欢空的impl,我的问题是空的impl。这是我试图避免的。@kukudas:然后在超类中使该方法为空,并在B中省略它。