我对OOP实现和设计模式有疑问。
我有一个固定的类模型,我无法更改(因为它是每次应用程序启动时自动生成的)。有许多类具有等于以下示例的字段:正如您可以看到字段city
和streets
都包含在这两个类中。
public class A{
String city;
String street;
String name;
....//get methods
}
public class B{
String city;
String street;
String age;
....//get methods
}
我需要从两种类型的类中提取地址,并且我想用一种方法实现它(因为两次编写相同的代码似乎很愚蠢)。如果类模型可更改,我可以添加Addressable
和A
可以实现的新接口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());
}
在没有界面的情况下实现相同的最优雅的方法是什么?没有为不同的类编写相同的代码?
答案 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
类
它可能会破坏实际的客户代码
因此,如果要实现真正的适配器,还需要一个接口。
如上所述,如果不重新设计最低A
或B
,一个非常好的解决方案就很复杂。
作为解决方法,您可以定义Address
类,该类提供工厂方法以从Address
或A
实例创建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
行。