使用哪种设计模式(如果存在)?

时间:2017-08-16 09:02:28

标签: java oop design-patterns

我对OOP实现和设计模式有疑问。

我有一个固定的类模型,我无法更改(因为它是每次应用程序启动时自动生成的)。有许多类具有等于以下示例的字段:正如您可以看到字段citystreets都包含在这两个类中。

public class A{
   String city;
   String street;

   String name;

   ....//get methods
}

public class B{
   String city;
   String street;

   String age;

   ....//get methods
}

我需要从两种类型的类中提取地址,并且我想用一种方法实现它(因为两次编写相同的代码似乎很愚蠢)。如果类模型可更改,我可以添加AddressableA可以实现的新接口B

public interface Addressable{

     public String getStreet();
     public String getCity();
}

//somewhere in code
public Address getAddress(Addressable addressable){
      return new Address(addressable.getCity(), addressable.getStreet());
} 

在没有界面的情况下实现相同的最优雅的方法是什么?没有为不同的类编写相同的代码?

3 个答案:

答案 0 :(得分:3)

如果您无法更改A或B,则必然会出现降级解决方案。
一个简单而设计良好的解决方案当然会依赖于定义Address getAddress()A将实现的地址检索方法(B)的接口。

您还可以定义包装类:

public class WrapperA implements Addressable {

  private final A a;

  public WrapperA(A a) {
    this.a = a;
  }

  @Override
  public Address getAddress(){
     return new Address(a.getCity(), a.getStreet(), etc...);
  } 

}

但如果你不得不为许多课程复制这种代码,那可能会相当笨拙 此外,客户不再操纵A而是WrapperA类 它可能会破坏实际的客户代码 因此,如果要实现真正的适配器,还需要一个接口。

如上所述,如果不重新设计最低AB,一个非常好的解决方案就很复杂。

作为解决方法,您可以定义Address类,该类提供工厂方法以从AddressA实例创建B

public class Address{

    ... 
   String city;
   String street;
    ... 

   private Address(){
   }

   public static Address of(A a){
     return new Address(a.getStreet(), a.getCity(), ....);
   }

   public static Address of(B b){
     return new Address(b.getStreet(), b.getCity(), ...);
   }

}

然后根据需要使用这些方法在需求上创建地址。

答案 1 :(得分:2)

您可以编写adapters来提供通用界面。

public class AdpaterA implements Addressable {

  private final A a;

  public AdapterA(A a) {
    this.a = a;
  }

  @Override public String getStreet() {
    return this.a.street;
  }

  // other method is omitted as homework ;-)
}

然后您将使用适配器类进行进一步处理。

答案 2 :(得分:0)

我有类似的情况,在构建过程中会生成类。 (在我的例子中,构建过程将检查数据库,并为每个数据库表生成一个包含所有字段的类。)

您声明应用程序启动时会生成类。如果它们是在构建过程中生成的,则可以在构建过程中添加一个额外的元素,以改变生成的文件。在我的情况下,我们的构建服务器只是Linux,因此我在sed脚本中添加了ant行。