充满静态方法的类的设计注意事项

时间:2009-02-26 17:28:18

标签: design-patterns static

作为Swing开发人员多年,可能是一个Swing开发人员,我已经确定了很多用于布局组件的模式。例如,我经常创建与JLabel关联的组件。我经常写:

JPanel panel = new JPanel(new BorderLayout());
panel.add(label, BorderLayout.NORTH);
panel.add(list, BorderLayout.CENTER);

我经常这样做,我决定创建一个包含常用布局习语的类。然后我可以简单地说:

JPanel panel = LayoutPatterns.createNorthLabeledPanel(label, list);

...这大大减少了我的打字负担。

所以,现在我有一个大约有20个静态方法的类。该类没有状态 - 所有上下文都通过方法参数传递。

除了Java的Math类之外,我还没有看到任何完全由静态方法组成的类,并且没有状态。

一方面,这感觉不对。另一方面,我认为它没有任何问题。

这是一个好用的模式,还是表示代码嗅觉的东西?如果这种模式应用于不同的域,我应该关注一类静态的多线程使用吗?如果您在生产质量代码中看到过这种情况,您会犹豫不决吗?

9 个答案:

答案 0 :(得分:4)

我认为这种事情通常会带来糟糕的代码味道。但是,我和你在一起,在这种情况下我没有看到任何特别错误。

我认为你已经完美地解释并证明了你的设计。

考虑可能的替代方案,也许你可以继承JPanel并创建NorthLabelJPanel(或者甚至可以更好地创建一个包含JPanel的新类)。但是,我不确定这是否值得付出努力。我认为你的代码看起来会更加复杂,即使它可能是“通过本书”更好的方式。

我的2美分:)

答案 1 :(得分:4)

我认为这里唯一的问题是一种迫使你发明一个类的语言,其中-gasp-全局函数是完全合适的。 : - )

答案 2 :(得分:2)

我没有看到制作像这样的课的问题。如果该类在正常使用中有意义,以至于您永远不需要实例化它的实例,那么为什么不将这些方法设为静态呢?

我自己编写了类似的代码。

答案 3 :(得分:2)

静态实用程序类没有任何问题,只要事情不会失控。如果您放入的方法不需要任何状态,则没有理由将您的类实例化。

事实上,情境非常普遍,在.Net中,扩展方法必须在静态类中,因为大多数情况下,实用程序函数是静态的,并尝试扩展另一种类型的功能。

答案 4 :(得分:1)

我没有看到你的方法有任何问题,事实上,我一直在做这些实用程序静态类。因为这个类没有任何状态,我认为你在多线程环境中没有任何问题。如果您关注这个班级的规模,请考虑根据某些类型的挥杆组件进行划分。

答案 5 :(得分:1)

似乎每个项目迟早会以静态实用程序类结束。对于您的特定示例,我可能会查看工厂模式。但如果能帮助你完成工作并且不会让团队中的其他人感到困惑,我认为你所做的事情没有任何问题。

答案 6 :(得分:0)

VB.NET和现在C#甚至对静态类有语言支持(VB称它们为模块),所以你可以让编译器检查它们确实是静态的。

答案 7 :(得分:0)

就个人而言,我更愿意看到您所描述的原始形式的代码。一目了然地更准确地说出代码正在做什么,并且更容易维护,因为如果您想要更改面板的布局,则不必搜索正确的方法或创建全新的方法实现你想要的。此外,当您向组件添加更多属性时,静态方法的数量将以指数速率增长。

在设计模式的世界中,我看到Builder模式应用于这样的案例,它似乎是Java API试图实现的目标。

基本纲要:

  1. 创建一个简单的对象,很少或没有装饰
  2. 添加对象/属性/等。让它看起来/做你想做的事
  3. 注意:美妙之处在于,在完成之前,您不知道最终结果会是什么样的,这将为您提供全方位的灵活性。

    此外,我刚刚阅读了一篇讨论扩展JPanel的回复。从设计的角度来看,记住要尽可能地尝试使用has-a关系而不是is-a关系。否则,你最终会得到一个看起来与你的静态方法相同的非常平坦的类结构,并且会遇到与我上面描述的相同的陷阱。

    现在说,我已经编写并使用了大量我称之为“服务”的集合,这些类没有状态和静态方法(正如你所描述的那样),它们使我免于写作(和更重要的是,复制了很多我的基本惯例。如果使用得当,它们可以派上用场,但我倾向于只将它们用于非常基本的(和常见的)例程,例如格式化文本,复制数组,将float数组转换为双数组(在C ++中)或其他任何你期望在标准库中找到它。

    这实际上取决于静态方法的“静态”程度。如果你不经常看到它们需要维护或更新,那么你可能会把它们锁定到你所描述的内容。但是,如果将来有任何重新分解的可能性,我认为您应该尽可能将其保留为flexibile,不幸的是,这意味着每次都要手动调用API。

    祝你好运!

答案 8 :(得分:0)

我认为如果您是在面向对象的环境中开发,那么您只有两个选择:

  1. 将所有类方法设为静态。
  2. 开发一个常规类并使用单例模式。