1

假设我有一个 Swing GUI,它必须以两种不同的方式显示某种类型的信息。从设计模式的角度来看,这里可能会使用策略模式:创建一个接口来定义显示组件和客户端之间的通信方式,如下所示:

public interface Foo {
  void showData(Data bar)
}

然后,真正的动作由实现 Foo 的不同组件完成,并且可以创建和插入以完成实际工作。

现在,如果真正的组件是 java.awt.Components,会发生什么?正如我所看到的,它会导致类型转换混乱,因为 Component 是一个类。让我们假设一个像这样的实现:

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

如果我想传递 Baz 类的对象,这些方法可以使用“Component”作为参数类型或“Foo”。问题是某些方法需要既是 Component 又是 Foo 的对象(例如,因为它们将对象添加到 JPanel,然后提供调用接口方法的数据showData())。

正如我所看到的,我有一些选择可以实现这一点:

  • 我可以将引用作为组件传递并转换为 Foo。之前,我必须检查引用是否是 Foo 的实例,并且我必须处理不满足此要求的情况。另一个问题是我必须与组件传递的方法的客户端进行通信,还必须实现 Foo,这很尴尬且容易出错。
  • 我可以用 Foo 做同样的事情
  • 我可以向 Foo 接口添加一个方法“Component getComponent()”,并且实现将始终返回“this”。这个样板方法可以放入 Component 的抽象子类中。这个解决方案意味着一个我不想要的接口方法和一个我不需要的额外子类。
  • 我可以传递两个引用,一个 Component 和一个 Foo 引用到同一个对象。不过,在内部,我必须确保两个引用都属于同一个对象。我必须处理不满足此要求的情况。
  • 我可以使用 Component 的抽象子类并使用抽象方法定义接口。这将允许我以类型安全的方式传递引用,但打破了良好的 OOP 实践:保持接口和实现分离以及接口隔离原则。

因此,所有这些解决方案都只是变通方法。有什么我缺少的解决方案吗?我应该怎么办?

4

1 回答 1

0

我会使用您提到的策略设计模式,但可能在不同的上下文中。尝试将“鞋拔”并入一个类的问题Foo在于Component,您可能拥有需要复制代码的实现组合。

例如,假设您有以下实现Component:(我使用 Swing 已经太久了,这些类可能不存在)

  • 面板
  • 按钮
  • 菜单

而且您还具有以下实现Foo

  • 我的福
  • 他的福
  • 我们的Foo
  • WhatTheFoo

想象一下这些的所有组合:这就是所谓的阶级爆炸。这是策略模式的经典理由。

我会创建一种容器类,它HAS-A为每个需要的类使用关系,而不是使用IS-A如下关系:(我是 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。然后可以根据需要组合ComponentandFoo实现,而不必复制 Foo impl 代码。另请注意,您可以调用类似模板模式的方法,doAction()这些方法可以在不知道其详细信息的情况下对两者进行操作FooComponent

要解决原始问题的问题:

  • Component需要 a 时,调用getComponent()处理程序实例
  • Foo需要 a 时,调用getFoo()处理程序实例
  • 我会避免创建同时需要的方法并将方法 args 拆分为 2
  • 或者只是考虑传递一个ComponentFooHandler
于 2012-04-23T10:00:46.327 回答