您可以将Wrapper和Visitor结合起来解决您的问题.
使用包装器添加访问方法可以增加这些对象的可用性.当然,你可以获得包装器的全部优点(对遗留类的依赖性较小)和缺点(附加对象).
这是JAVA中一个经过深思熟虑的例子(因为它非常严格,不会单独进行双重调度,而且我对它非常熟悉):
1)您的旧对象
假设您有遗留对象Legacy1和Legacy2,您无法更改,具有特定的业务方法:
public final class Legacy1 {
public void someBusinessMethod1(){
...
}
}
和
public final class Legacy2 {
public void anotherBusinessMethod(){
...
}
}
2)准备包装器
你只需将它们包装在一个VisitableWrapper中,它有一个访问方法,可以访问你的访问者,如:
public interface VisitableWrapper {
public void accept(Visitor visitor);
}
通过以下实现:
public class Legacy1Wrapper {
private final Legacy1 legacyObj;
public Legacy2Wrapper(Legacy1 original){
this.legacyObj = original;
}
public void accept(Visitor visitor){
visitor.visit(legacyObj);
}
}
和
public class Legacy2Wrapper {
private final Legacy2 legacyObj;
public Legacy2Wrapper(Legacy2 original){
this.legacyObj = original;
}
public void accept(Visitor visitor){
visitor.visit(legacyObj);
}
}
3)访客,准备好了!
然后可以设置您自己的访问者访问包装器,如下所示:
public interface Visitor {
public void visit(Legacy1 leg);
public void visit(Legacy2 leg);
}
有这样的实现:
public class SomeLegacyVisitor{
public void visit(Legacy1 leg){
System.out.println("This is a Legacy1! let's do something with it!");
leg.someBusinessMethod1();
}
public void visit(Legacy2 leg){
System.out.println("Hum, this is a Legacy 2 object. Well, let's do something else.");
leg.anotherBusinessMethod();
}
}
4)释放力量
最后在您的代码中,此框架将如下工作:
public class TestClass{
// Start off with some legacy objects
Legacy1 leg1 = ...
Legacy2 leg2 = ...
// Wrap all your legacy objects into a List:
List visitableLegacys = new ArrayList<>();
visitableLegacys.add(new Legacy1Wrapper(legacy1));
visitableLegacys.add(new Legacy2Wrapper(legacy2));
Visitor visitor = new SomeLegacyVisitor(); // Use any of your visitor implementation !
for(VisitableWrapper wrappedLegacy: visitableLegacys){
wrappedLegacy.accept(visitor);
}
}
预期产量:
This is a Legacy1! let's do something with it!
Hum, this is a Legacy 2 object. Well, let's do something else.
缺点:
>相当多的样板.如果使用Java开发,请使用Lombok.>相当多的包装器对象实例.可能或可能不是你的问题.>您需要事先知道对象的具体类型.这意味着您知道它们的子类型,它们不是List中的包.如果是这种情况,除了使用反射之外别无选择.