2012-04-22 32 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

相关问题