我一直在使用委托模式来包装由工厂在第三方库创建的对象。 近日,该库在基类中增加了一个受保护的方法和我的包装类不下去了工作。 有没有人有不诉诸反射好的解决办法?
这是第三方库,并在其包装,
public class Base {
public void foo();
protected void bar(); // Newly added
}
这是我自己的包,
public class MyWrapper extends Base {
private Base delegate;
public MyWrapper(Base delegate) {
this.delegate = delegate;
}
public void foo() {
delegate.foo()
}
protected void bar() {
// Don't know what to do
}
}
编辑:我原来的职位还不清楚。 这2类在不同的包。
要回答这个问题,为什么我需要的代表团。 这是代表团/包装图案的典型使用情况,我不能在几行代码在这里表现出来。 该库公开Base类但是从他们的工厂实际的对象是一个派生类基地。 实际的类的变化取决于配置。 因此,我不知道什么是委托。 因此直继承格局不在这里工作了。
Access Levels
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
protected
具有package
访问过,你看任何具体问题与此:
class Base {
public void foo(){};
protected void bar(){}; // Newly added
}
class MyWrapper {
private Base delegate;
public MyWrapper(Base delegate) {
this.delegate = delegate;
}
public void foo() {
delegate.foo();
}
protected void bar() {
// Don't know what to do
delegate.bar(); //since its in same package, it can be referenced, do you expect compile time error?
}
}
此外,同时使用委托模式为什么包装类扩展Base
类,我没有看到具体的需要,因为你已经有实例Base
。 对我来说,似乎更有一种装饰的。
你并不需要(或不应该?)委托那家酒吧的方法。
如果库中定义一个受保护的方法。 它不希望用户(当然在不同的封装体)来调用该方法中,除非创建该类型的子类。 您正在试图打破规则。
如果你想这样做,有办法,你创建的一个亚型Base
,说SubBase
,为您打造的对象SubBase
,而不是Base
,然后通过subBase
到您的包装。 然后你在你的包装可能bar()
方法写delegate.bar()
这样的SubBase
实际上是代表,或者说你的包装是委托SubBase
不Base
我想你明白我的意思,所以我只是不键入例如代码,仅此行中我想这就够了:
//Wrapper
private SubBase delegate;
你看包装是没有必要下去,如果你有SubBase
。 你甚至可以定义一个public void pubBar()
在SubBase
,在那里你调用this.bar()
以这种方式底基层所有对象都具有访问受保护的方法( via pubBar()
无论从哪个包
我得到的印象是Base
类是一个接口或抽象类。 如果是这样,你必须实现bar()
通过使用任何下列三种方法中的方法,例如。
侧面说明,如果Base
是一个普通的类,你没有做任何事情(以实例的调用MyWrapper.bar()
实际上将导致一个呼叫Base.bar()
委托给其父对象
这通常是一个好主意,如果bar()
方法作为第三方API的回调:
@Override
protected void bar() {
delegate.bar();
}
没做什么
只需添加一个空的方法来避免编译错误:
@Override
protected void bar() {
// silently ignored
}
抛出一个异常
猛烈地防止了新方法的任何使用:
@Override
protected void bar() {
throw new UnsupportedOperationException("not implemented");
}
作为一个方面说明,结构更坚固,是喜欢组成了继承从第三方执行,例如解耦实现
public class MyWrapper { // does not extend Base
private Base delegate;
public MyWrapper(Base delegate) {
this.delegate = delegate;
}
public void foo() {
delegate.foo()
}
// does not have to implement bar()
}
我使用Spring在包装注入来自另一模块“基本代表”,并为获得委托我使用POJO工厂。
<bean id="interfaceDelegate" factory-bean="DelegatePojoFactory"
factory-method="getMyDelegateInstance">
<constructor-arg index="0">
<value>OnLine</value>
</constructor-arg>
</bean>
<bean id="wrapper" class="path.Wrapper">
<property name="delegate" ref="interfaceDelegate"></property>
</bean>
如果你不需要你的委托方是基类的一个实际的实例,你可以简单地删除该关系:
public class MyWrapper {
private Base delegate;
public MyWrapper(Base delegate) {
this.delegate = delegate;
}
public void foo() {
delegate.foo()
}
}
无论是为你工作是高度依赖于你的其他代码,您的需求,现在还没有完全清晰。
如果库定义提供它是由抽象基类实现公共方法的接口,你可以理智地实现该接口不从抽象基类,也可能满足你的需要继承。