简体   繁体   English

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

[英]Java/Patterns for hiding methods from third party classes

I have a class A that has a series of handlers eg public void handleEv1(),public void handleEv2() etc. When an event occurs, another thread in class B, calls the correspondent handler from class A (class B has a reference to class A kind of observer-observable). 我有一个类A,它具有一系列处理程序,例如public void handleEv1(),public void handleEv2()等。发生事件时,B类中的另一个线程从A类调用对应的处理程序(B类具有对类一种观察者可观察的)。 In the handling of the event in the corresponding method of class A, A eventually raises an event to an eventListener (class C which is not created by me). 在使用类A的相应方法处理事件时,A最终将事件引发给事件监听器(不是我创建的类C)。 My question is the following: is there a pattern I can use to "hide" the handling methods of class A from the classes that act as eventListeners (not implemented by me), and be "visible/accesible" only to class B (which I implement)? 我的问题如下:是否有一种模式可以用来“隐藏”充当事件监听器的类(不是由我实现)中的类A的处理方法,并且仅对类B是“可见/可访问”的(我实施)?

I am editing my original question. 我正在编辑我的原始问题。 I have class Csystem that has a lot of methods and the handlers I am talking about 我有一个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 is a class that is essentially an interface for other developers of other components to my code. CSystem是一个类,该类本质上是我的代码的其他组件的其他开发人员的接口。 Some other developer will write his own version of class AListener (class A) and use Csystem in his code. 其他一些开发人员将编写自己的类AListener(类A)的版本,并在其代码中使用Csystem。 Whenever an event occurs somewhere (eg a message in the network arrived) class B will pass the event to the event handlers of CSystem 每当某个地方发生事件(例如,网络中的消息到达)时,类B会将事件传递给CSystem的事件处理程序

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

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

} My problem is that both class Dispatch (implemented by me) and class AListener "see" the same interface of CSystem. 我的问题是Dispatch类(由我实现)和AListener类都“看到”了CSystem的相同接口。 I would like the developers who implement the AListener to see a different view of CSystem and "see" and be able to use only methods that are public. 我希望实现AListener的开发人员可以看到CSystem的不同视图并“查看”,并且只能使用公共方法。 I don't think that it is a good idea to see methods someone actually can not use (handlers are meaningful to be used only by dispatcher) Is there a pattern to achieve this? 我认为查看某人实际上无法使用的方法不是一个好主意(处理程序对于仅由调度程序使用是有意义的)是否有实现此目标的模式?

Thank you! 谢谢!

Use Interfaces. 使用接口。 B's relationship with A is only via an Interface that B defines and A implements. B与A的关系仅通过B定义和A实现的接口来实现。

So from B's perspective, it doesn't even import A, or have access to the definition of A at compilation time. 因此,从B的角度来看,它甚至不会导入A,也不会在编译时访问A的定义。

Edited in response to question. 编辑以回应问题。

I beleive you have a class C 我相信你有C类

pre-existing, unchangable by you, code in some package xy; 预先存在的,您无法更改的,在某些软件包xy中的代码;

Class CEvent {
   // some event definition
};

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

--- code you write --- ---您编写的代码---

package p.q;
public Class A implements BEventInterface {

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

}

And your concern is that anybody , even including C could call that bEventHappened() method. 您担心的是,甚至包括C在内的任何人都可以调用该bEventHappened()方法。

My feeling is that you're concerned by an unlikely problem. 我的感觉是您担心一个不太可能的问题。 Why would someone go to the trouble of creating an A object and doing that? 为什么有人会麻烦创建一个A对象并这样做呢? However there are some possibilities: 但是,有一些可能性:

1). 1)。 If A and B are in the same package, do not make A and it's method public. 如果A和B在同一个程序包中,请不要将A及其方法公开。 Only B needs to see them, so at package scope this will just work. 只有B才需要查看它们,因此在包范围内这将起作用。

2). 2)。 Anonymous inner class. 匿名内部类。 Note here that A ia class with a no public methods, so C can't use it and yet B has public methods on the anonymous inner class it can use. 请注意,这里的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() );
}
}

With classes B and C looking like: 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;
}

}

and

package x.y.z;

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

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

} }

You appear to have a class with an interface with multiple responsibilities. 您似乎有一个带有多个职责界面的类。 This is a bad thing. 这是一件坏事。 A simple approach is to use anonymous inner classes to implement callback interfaces. 一种简单的方法是使用匿名内部类来实现回调接口。

You can put A and B in package alpha and C in package omega. 您可以将A和B放在包alpha中,将C放在omega包中。 A and B have access to each other's package private members, but C does not. A和B可以访问彼此的包私有成员,而C则不能。 You should also use interfaces like djna said. 您还应该使用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 ) ; ... }

You can do this like that: 您可以这样做:

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);
    }
}

thank you for your example! 谢谢你的榜样! I was not clear it seems. 我似乎还不清楚。 I have class Csystem that has a lot of methods and the handlers I am talking about 我有一个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 is a class that is essentially an interface for other developers of other components to my code. CSystem是一个类,该类本质上是我的代码的其他组件的其他开发人员的接口。 Some other developer will write his own version of class AListener (class A) and use Csystem in his code. 其他一些开发人员将编写自己的类AListener(类A)的版本,并在其代码中使用Csystem。 Whenever an event occurs somewhere (eg a message in the network arrived) class B will pass the event to the event handlers of CSystem 每当某个地方发生事件(例如,网络中的消息到达)时,类B会将事件传递给CSystem的事件处理程序

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

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

}

My problem is that both class Dispatch (implemented by me) and class AListener "see" the same interface of CSystem. 我的问题是Dispatch类(由我实现)和AListener类都“看到”了CSystem的相同接口。 I would like the developers who implement the AListener to see a different view of CSystem and "see" and be able to use only methods that are public. 我希望实现AListener的开发人员可以看到CSystem的不同视图并“查看”,并且只能使用公共方法。 I don't think that it is a good idea to see methods someone actually can not use (handlers are meaningful to be used only by dispatcher) Is there a pattern to achieve this? 我认为查看某人实际上无法使用的方法不是一个好主意(处理程序对于仅由调度程序使用是有意义的)是否有实现此目标的模式?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM