Java的:委托模式和受保护的方法(Java: Delegation Pattern and Pro

2019-09-01 04:43发布

我一直在使用委托模式来包装由工厂在第三方库创建的对象。 近日,该库在基类中增加了一个受保护的方法和我的包装类不下去了工作。 有没有人有不诉诸反射好的解决办法?

这是第三方库,并在其包装,

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类但是从他们的工厂实际的对象是一个派生类基地。 实际的类的变化取决于配置。 因此,我不知道什么是委托。 因此直继承格局不在这里工作了。

Answer 1:

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 。 对我来说,似乎更有一种装饰的。



Answer 2:

你并不需要(或不应该?)委托那家酒吧的方法。

如果库中定义一个受保护的方法。 它不希望用户(当然在不同的封装体)来调用该方法中,除非创建该类型的子类。 您正在试图打破规则。

如果你想这样做,有办法,你创建的一个亚型Base ,说SubBase ,为您打造的对象SubBase ,而不是Base ,然后通过subBase到您的包装。 然后你在你的包装可能bar()方法写delegate.bar()这样的SubBase实际上是代表,或者说你的包装是委托SubBaseBase

我想你明白我的意思,所以我只是不键入例如代码,仅此行中我想这就够了:

//Wrapper

 private SubBase delegate;

你看包装是没有必要下去,如果你有SubBase 。 你甚至可以定义一个public void pubBar()SubBase ,在那里你调用this.bar() 以这种方式底基层所有对象都具有访问受保护的方法( via pubBar()无论从哪个包



Answer 3:

我得到的印象是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()
}


Answer 4:

我使用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>


Answer 5:

如果你不需要你的委托方是基类的一个实际的实例,你可以简单地删除该关系:

public class MyWrapper {
    private Base delegate;

    public MyWrapper(Base delegate) {
        this.delegate = delegate;
    }

    public void foo() {
        delegate.foo()
    }

}

无论是为你工作是高度依赖于你的其他代码,您的需求,现在还没有完全清晰。

如果库定义提供它是由抽象基类实现公共方法的接口,你可以理智地实现该接口不从抽象基类,也可能满足你的需要继承。



文章来源: Java: Delegation Pattern and Protected Methods