干掉这些类的最佳方法是什么,除了构造函数之外的所有内容都是重复的

时间:2010-07-09 15:47:41

标签: java oop refactoring dry

所以我做了一些重构,现在我的两个类看起来完全一样,除了它们的构造函数。

这些类包装了一个不太漂亮的API对象,并添加了属于API边缘的一些功能。

class A extends API {
  public A {
    this.APIOption = Option1;
    this.AnotherAPIOption = Option2;
    // a few more
  }

  public ArrayList<String> somethingTheAPIDoesntDo() {
    // Do something the API doesn't provide but I use alot
  }
  // Other shared methods
}

class B extends API {
  public B {
    this.APIOption = Option3;
    this.AnotherAPIOption = Option4;
    // a few more
  }

  public ArrayList<String> somethingTheAPIDoesntDo() {
    // Do something the API doesn't provide but I use alot
  }
  // Other shared methods
}

将两者之间的公共代码推送到Abstract Base类是否有意义,并且子类只使用专门的选项设置实现其构造函数? 它在纸上是有道理的,但有些东西对它感到怪异/违反直觉。我在这里错过了一个模式吗?

可能的DRYer解决方案

class A extends BetterAPIBase {
  public A {
    this.APIOption = Option1;
    this.AnotherAPIOption = Option2;
    // a few more
  }
}

class B extends BetterAPIBase {
  public B {
    this.APIOption = Option3;
    this.AnotherAPIOption = Option4;
    // a few more
  }
}    

abstract class BetterAPIBase extends API {
  public Better APIBase() {}
  public ArrayList<String> somethingTheAPIDoesntDo() {
    // Do something the API doesn't provide but I use alot
  }
  // Other methods
}

修改

静态工厂模式很不错,但我想我也可以添加一个包含我添加的常用方法的接口。

我会让BetterAPI类同时实现IBetterAPI,这只会在我将实例的类型声明为IBetterAPI时公开我添加的方法。

interface IBetterAPI{
      public ArrayList<String> somethingTheAPIDoesntDo();
      // other methods I added in BetterAPI
}

//somewhere else:
IBetterAPI niceApi = BetterAPI.createWithOptionSetA();
niceApi.somethingTheAPIDoesntDo();

// Can't do this, nice and hidden.
niceApi.somethingBaseAPIDoes(string uglyOptions, bool adNauseum); 

2 个答案:

答案 0 :(得分:13)

让一个类具有参数化(可能是私有的)构造函数和多个静态工厂方法会不会更简单?

class BetterAPI extends API {
  private BetterAPI(APIOption option, AnotherAPIOption anotherOption) {
    this.APIOption = option;
    this.AnotherAPIOption = anotherOption;
  }

  public static BetterAPI createWithOptionSetA() {
    return new BetterAPI(Option1, Option2);
  }

  public static BetterAPI createWithOptionSetB() {
    return new BetterAPI(Option3, Option4);
  }

  // ...
}

您的问题的核心似乎是您不能在同一个类中拥有多个无参数构造函数。静态工厂方法为此提供了一个很好的解决方案。

答案 1 :(得分:1)

这与我的工作非常接近。虽然如果“少数几个”在构造函数中产生了大量冗余代码,我会写:

abstract class BetterAPIBase extends API { 
  public BetterAPIBase(String APIOption, int AnotherAPIOption, ... more ...) {
    this.APIOption=APIOption;
    this.AnotherAPIOption=AnotherAPIOption;
    // a few more
  } 
  public ArrayList<String> somethingTheAPIDoesntDo() { 
    // Do something the API doesn't provide but I use alot 
  } 
  // Other methods 
} 

class A extends BetterAPIBase { 
  public A { 
    super(Option1, Option2, ... more ...);
  } 
} 

class B extends BetterAPIBase { 
  public B { 
    super(Option3, Option4, ... more ...);
  } 
}     

当然,如果任何选项值相同,那么它们就不需要传递,这就是消除真正冗余的地方。