用于从第三方类隐藏方法的Java /模式

时间:2010-07-06 06:17:10

标签: java design-patterns oop

我有一个A类,它有一系列处理程序,例如public void handleEv1(),public void handleEv2()等。 当一个事件发生时,B类中的另一个线程从A类调用相应的处理程序(B类引用了A类的observer-observable)。 在A类的相应方法中处理事件时,A最终将事件引发到eventListener(C类,它不是由我创建的)。 我的问题如下:是否有一种模式可以用来从作为eventListeners的类(我没有实现)中“隐藏”类A的处理方法,并且只对B类“可见/可访问”我实施了吗?

我正在编辑原始问题。 我有类Csystem,它有很多方法和我正在讨论的处理程序

public class Csystem()
{

   private AListener listener;//implements an event listener (the class C in my question)

//some methods here
 public void handleEventIncoming(Event e){
//Do some logic here
  listener.raiseEvent(e);
 }
 public void handleEventOutgoing(Event e); etc


}

CSystem是一个类,它本质上是我的代码中其他组件的其他开发人员的接口。其他一些开发人员将编写自己的类AListener(A类)并在其代码中使用Csystem。只要某个事件发生在某个地方(例如网络中的消息到达),B类就会将事件传递给CSystem的事件处理程序

public class Dispatch{
//This is class B
 private CSystem s;

 private void event_occured(Event e)
 {
    s.handleEventIncoming(e);
 }
}   

} 我的问题是,类Dispatch(由我实现)和类AListener“看到”CSystem的相同接口。我希望实现AListener的开发人员能够看到CSystem的不同视图并“看到”,并且只能使用公开的方法。我不认为看到某人实际上无法使用的方法是个好主意(处理程序只有调度员使用才有意义)是否有实现此目的的模式?

谢谢!

5 个答案:

答案 0 :(得分:3)

使用接口。 B与A的关系只能通过B定义的接口和A实现。

因此从B的角度来看,它甚至不会导入A,或者在编译时可以访问A的定义。

在回答问题时编辑。

我相信你有一个C级

预先存在,不可更改,代码在某个包x.y;

Class CEvent {
   // some event definition
};

Class C {
    public void callWhenitHappens(CEvent theEvent) {
       // do something
    }
}

---你写的代码---

package p.q;
public Class A implements BEventInterface {

   public void bEventHappened( BEvent theBEvent ){
       // make a C event
       myC.callWhenitHappens(theCEvent);
   }

}

你担心的是任何人,甚至包括C都可以调用bEventHappened()方法。

我的感觉是你担心一个不太可能出现的问题。为什么有人会遇到创建A对象并执行此操作的麻烦?但是有一些可能性:

1)。如果A和B在同一个包中,请不要将A和它的方法设为公共。只有B需要看到它们,因此在封装范围内这将起作用。

2)。匿名内部阶级。注意这里的A ia类没有公共方法,所以C不能使用它而且B在它可以使用的匿名内部类上有公共方法。

package p.q;

import p.q.B.BEvent;
import x.y.z.C.CEvent;
import x.y.z.C;

public class A  {

// anonymous class implementing required interface
private BListener myFacade = new BListener(){
    @Override
    public void listen(BEvent event) {
        bEventHappened(event);          
    }       
};

private B myB;
private C myC;

A() {
    myC = new C();
    myB = new B();
    myB.registerListener(myFacade);
}

private void bEventHappened( BEvent theBEvent ){
       myC.callWhenitHappens(myC.new CEvent() );
}
}

B类和C类看起来像:

package p.q;

public class B {

public class BEvent {
    public String what;
}

private BListener myListener;

private void fireEvent(){
    myListener.listen(new BEvent());
}

public void registerListener(BListener listener){
    myListener = listener;
}

}

package x.y.z;

public class C {
public class CEvent {
    public String what;
}

public void callWhenitHappens(CEvent event){
    //e3c
}

}

答案 1 :(得分:1)

您似乎拥有一个具有多个职责的界面的类。这是件坏事。一种简单的方法是使用匿名内部类来实现回调接口。

答案 2 :(得分:0)

您可以将A和B放在包中的alpha和C包omega中。 A和B可以访问彼此的包私有成员,但C没有。您还应该使用像djna这样的接口。

package alpha ;
public interface A { void doSomething ( ) ; }
public interface B { }
class AImpl implements A { ... void doSomethingPrivate ( ) { ... } }
class BImpl implements B { AImpl a ; ... a.doSomethingPrivate ( ) ; }

package omega ;
public interface C { public void handle ( alpha.a a ) ; ... }

答案 3 :(得分:0)

你可以这样做:

interface EventSource<T>{ 
    void addEventListener(T listener);
    void removeEventListener(T listener);
}
class B implements EventSource<SomethingListener>
{
    A instA;
    ...
    public B(A instA)
    {
        this.instA = instA;
        instA.installEventSource(this);
        ...
    }
    ...
} 
class A
{
    ...
    public void installEventSource(EventSource source)
    {
        source.addEventListener(listener);
    }
    public void uninstallEventSource(EventSource source)
    {
        source.removeEventListener(listener);
    }
}

答案 4 :(得分:0)

谢谢你的榜样! 我好像不清楚。 我有类Csystem,它有很多方法和我正在讨论的处理程序

public class Csystem()
{

private AListener listener;//implements an event listener (the class C in my question)

//methods here
 public void handleEventIncoming(Event e){
//Do some logic here
  listener.raiseEvent(e);
 }
 public void handleEventOutgoing(Event e); etc


}

CSystem是一个类,它本质上是我的代码中其他组件的其他开发人员的接口。其他一些开发人员将编写自己的类AListener(A类)并在其代码中使用Csystem。 只要某个事件发生在某个地方(例如网络中的消息到达),B类就会将事件传递给CSystem的事件处理程序

public class Dispatch{
//This is class B
private CSystem s;

 private void event_occured(Event e)
 {
    s.handleEventIncoming(e);
 }
}   

}

我的问题是,类Dispatch(由我实现)和类AListener“看到”CSystem的相同接口。我希望实现AListener的开发人员能够看到CSystem的不同视图并“看到”,并且只能使用公开的方法。我不认为看到某人实际上无法使用的方法是个好主意(处理程序只对调度员有用) 是否有实现这一目标的模式?