2010-07-06 59 views
0

我有一個A類,有一系列處理程序,例如public void handleEv1(),public void handleEv2()等 當一個事件發生時,類B中的另一個線程,調用A類的通信者處理程序(B類具有對A類觀察者可觀察類的引用)。 在A類的相應方法中處理事件時,A最終將事件引發至eventListener(不由我創建的類C)。 我的問題是:是否有一種模式可以用來將類A的處理方法從作爲事件監聽器的類中「隱藏」(不是由我來實現),並且只對類B「可見/可訪問」我執行)?Java /用於從第三方類隱藏方法的模式

我正在編輯我的原始問題。 ,有很多的方法和處理我所說的

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我有類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); 
} 
} 

} 我的問題是,無論是類分(通過我實現)和類AListener 「看到」CSystem的相同界面。我希望實現AListener的開發人員能夠看到CSystem的不同視圖,並「看到」並且只能使用公開的方法。我不認爲看到某個人實際上不能使用的方法是一個好主意(處理程序只有調度員纔有意義)是否有一種模式可以實現這一點?

謝謝!

回答

3

使用接口。 B與A的關係只能通過B定義和A實現的接口。

因此,從B的角度來看,它甚至不會導入A,或者在編譯時訪問A的定義。

針對問題編輯。

我beleive你有一些包一個xy格式C類

預先存在的,通過你unchangable,代碼;

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)。匿名內部類。注意這裏有一個沒有公共方法的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 
} 

}

+0

嗨, 你是指以下? 公共類B接口處理程序public void handleEv1(); public void handleEv1(); } etc } class A implements Handlers { public void handleEv1(); public void handleEv1(); etc } 但是這個設計仍然不是C仍然可以訪問的處理程序,因爲它們是公開的?或者我誤解你在說什麼? – akmer 2010-07-06 10:53:37

+0

但是你的A向C發送了一個事件,C不知道A的任何內容,它在編寫A之前就被編譯了,C中沒有任何代碼能夠知道anA.myMethod()。 – djna 2010-07-06 11:12:20

+0

感謝您的回覆。對我來說問題是以下(可能是我的想法是錯誤的):我有類A作爲類B和類C之間的邊界。類A具有註冊爲偵聽器的類C。類B在事件發生時調用A的handlerMethods並且該方法執行一些處理並將事件引發到C.但是A的處理程序方法是公共的。 A被用作接口來代碼,我沒有實現,並希望如果處理程序方法具有私人範圍,以便C例如不能調用類A的處理程序。那麼,我應該如何重新設計我的類來實現這一目標?謝謝! – akmer 2010-07-06 11:32:24

0

你可以把A和B在包歐米加包阿爾法和C。 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) ; ... } 
+0

放置是相同的包解決這個問題,但不幸的是我沒有這個選項,因爲我沒有開始從頭開始編碼,這部分(包)已經存在 – akmer 2010-07-06 11:01:08

1

您似乎有一個具有多個責任接口的類。這是一件壞事。一個簡單的方法是使用匿名內部類來實現回調接口。

+0

您能否舉一個你正在建議的小例子? – akmer 2010-07-06 10:59:11

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

所以在類A中,我引用了類B.當事件發生時,我將使用引用來調用相應的處理函數。但是這種方法的可見性是什麼?如果它是公開的,我仍然有同樣的問題。對? – akmer 2010-07-06 10:58:18

+0

'EventSource'是一個類。你可以使用插件系統(OSGI或Netbeans RCP)來隱藏它,或者將它放在'internal'包中 - 一個通用的約定是不在模塊外部使用這些類。 – 2010-07-07 05:01:55

0

感謝您的例子! 我似乎並不清楚。 ,有很多的方法和處理我所說的

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我有類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); 
} 
} 

} 

我的問題是,無論是類分(通過我實現)和類AListener「看到「CSystem的相同界面。我希望實現AListener的開發人員能夠看到CSystem的不同視圖,並「看到」並且只能使用公開的方法。我不認爲看到某些人實際上不能使用的方法是一個好主意(處理程序僅供調度員使用有意義) 有沒有一種模式可以實現這一點?

+0

我無法編輯我原來的問題,所以我在這裏擴展了我的原始問題的細節。非常遺憾! – Cratylus 2010-07-06 21:58:36