用于扩展实例的Java体系结构问题(需要模式推荐)

时间:2012-08-16 09:21:41

标签: java design-patterns inheritance dynamic extend

我不允许修改来自外部API的服务返回

  MyClass instance = ServiceUtil.getThing();

我想扩展这个返回的类并添加/覆盖一个方法但是留下其他的方法,比如150个方法。

  private class MyWrapperClass extends MyClass(){
      public MyWrapperClass(){super();}
      @Override public String toString(){ return "Blocked toString"; }
  }

有没有办法强制从返回的MyClass实例强制转换为新的特定子类型?

注意:请不要建议制作构造函数的方法,传递原始对象并且必须复制并实现150个方法来调用包装对象

3 个答案:

答案 0 :(得分:7)

如果MyClass是界面,请查看java.lang.reflect.Proxyjava.lang.reflect.InvocationHandler

您可以实现始终执行相同操作的动态代理。它总是将控制传递给你的原始实现......除非调用方法X.

类似的东西:

class MyHandler implements InvocationHandler {
  Object invoke(Object proxy, Method method, Object[] args) {
    if (method is the one you want to change) {
       do whatever
    else
       return method.invoke(originalObject, args);
  }
}

注意:无论如何必须创建此代理实现:

MyClass original = ServiceUtil.getThing();
MyClass proxy = (MyClass) Proxy.newProxyInstance(
                                          MyClass.class.getClassLoader(), // classloader to use
                                          new Class[] { MyClass.class }, // interfaces to implement
                                          new MyHandler()); // who does the dirty work when methods are invoked

答案 1 :(得分:5)

我希望我能帮到你:你有一个

MyClass instance = ServiceUtil.getThing();

但想要像

这样的东西
MyWrapperClass instance = (MyWrapperClass) ServiceUtil.getThing();

(即使MyWrapperClass扩展MyClass),这显然不起作用。

解决方案是基于MyWrapperClass创建MyClass的新实例,很遗憾地说,使用构造函数是一种很好的方法(public MyWrapperClass(MyClass myClass))。

答案 2 :(得分:1)

  

请不要建议制作构造函数的方法,传递原始对象   并且必须复制并实现150个方法来调用包装对象

你的意思是说“装饰”不是你想看的选项吗?

但是,如果MyClass是一个接口类型,你需要定义那些150多个方法,将149个方法调用委托给装饰并覆盖一个方法,装饰将是一个问题。

如果MyClass是类类型,那么你不需要编写这149种方法,对吧?或者我完全错了吗?