2012-04-22 57 views
1

假設我有一個Swing GUI,它必須以兩種不同的方式顯示特定類型的信息。從設計模式的角度一個可能會在這裏使用的策略模式:創建定義的界面顯示組件和客戶端之間的通訊是如何工作原理是這樣:AWT組件和自定義接口類型:如何編寫好的OOP代碼?

public interface Foo { 
    void showData(Data bar) 
} 

的實際行動,然後通過不同的組件做到了實現Foo,並且可以創建並插入進行真正的工作。

現在,如果真實組件是java.awt.Components,會發生什麼?正如我所看到的,它會導致類型轉換混亂,因爲Component是一個類。讓我們假設這樣一個實現:

public class Baz extends Component implements Foo { 
    ... 
} 

如果我想通過周圍類巴茲的對象,方法既可以使用「組件」作爲參數類型或「富」。問題是某些方法需要Component和Foo對象(例如,因爲它們將對象添加到JPanel中,然後提供調用接口方法showData()的數據)。

當我看到它,我有一些選擇來實現這一目標:

  • 我可以通過參考作爲組件和轉換爲富。之前,我必須檢查引用是否爲Foo的實例,並且我必須處理不滿足此要求的情況。另一個問題是,我必須向客戶傳達組件傳遞的方法還必須實現Foo,這非常容易出錯並且容易出錯。
  • 我可以用Foo做同樣的事
  • 我可以給Foo接口添加一個方法「Component getComponent()」,實現總是返回「this」。這個樣板方法可以放入Component的抽象子類中。這個解決方案意味着我不需要的接口方法和另外一個我不需要的子類。
  • 我可以將兩個引用,一個Component和一個Foo引用傳遞給同一個對象。但在內部,我必須確定兩個引用屬於同一個對象。而且我必須處理不符合這個要求的情況。
  • 我可以使用Component的抽象子類並使用抽象方法定義接口。這將允許我以類型安全的方式傳遞引用,但是打破了良好的OOP實踐:保持接口和實現獨立,並且還有接口隔離​​原則。

因此,所有這些解決方案都只是解決方法。我有什麼解決方案嗎?我該怎麼辦?

回答

0

我會像你提到的那樣使用策略設計模式,但也許在不同的上下文中。試圖將FooComponent「踩到」一個類的問題是,您可能需要複製代碼的實現組合。

例如,假設你有Component以下實現: (它太長久以來伊夫使用Swing中,這些類可能不存在)

  • 的JPanel
  • 的JButton
  • JMenu的

而且您還有以下實現Foo

  • MyFoo
  • HisFoo
  • OurFoo
  • WhatTheFoo

,想象那些的所有組合:這是什麼叫做類爆炸。這是戰略模式的經典理由。

我會創造一種容器類的使用,而不是使用IS-A關係如下爲每個需要的類的HAS-A關係: (IM一個C++程序員,所以你必須原諒混合代碼: )

class ComponentFooHandler { 
    Component component_; 
    Foo fooImpl_; 

    inline Foo getFoo() {return fooImpl_;} 
    void setFoo(Foo f) {fooImpl_ = f;} 

    Component getComponent()  {return component_;} 
    void setComponent(Component c) {component_ = c;} 

    void doAction() { 
    component_.someAction(); 
    fooImpl_.anotherAction(); 
    } 
} 

然後,您將不得不分別創建Foo的不同實現。然後,ComponentFoo實現可以根據需要進行組合,而不必重複Foo impl代碼。還要注意,您可以調用類似doAction()的方法,該方法可以在FooComponent之間運行,但不知道它們的詳細信息,類似於模板模式。

  • 當需要Component,呼籲getComponent()在處理程序實例
  • 當需要Foo,呼籲getFoo()在處理程序實例
  • 我:

    要使用你原來的問題解決問題將避免創建需要同時使用兩種方法的方法,並將方法參數拆分爲2

  • 或者僅考慮傳遞一個ComponentFooHandler
+0

好吧,但我的問題是沒有將Foo代碼與組件代碼分開。我的問題是,我的Foo實現是組件(例如JPanels),儘管我知道我不知道如何將這些知識放在代碼中,因此編譯器也可以檢查它。 – xmjx 2012-04-30 07:23:03

+0

好的,也許你應該考慮一下,如果你的Foo所暗含的是組件的必要性。如果你很難弄清楚如何使用這種設計,也許這意味着你應該考慮採用不同的設計。 – Brady 2012-04-30 09:00:34