3

免责声明:这个问题是针对那些认为 Scott Meyers 在 Effective C++ 第 23 条中的建议是好的 OO 设计的人——至少在 C++ 中是这样。

在不存在全局函数的 Java 中,乍一看这个原则似乎不适用,但在我看来它是适用的。以斯科特迈耶斯自己的例子为例。

public class WebBrowser {
    public void clearCache() {}
    public void clearHistory() {}
    public void removeCookies() {}
}

通过创建一个包含静态便利方法的关联“命名空间”类,我WebBrowser通过最小化可以访问其内部的代码量来增加封装。毕竟,Java 中的静态方法本质上是全局函数(假设类中的所有内容都是公共的和静态的)。

public class WebBrowserStuff {
    private WebBrowserStuff() {} // prevent instantiation

    public static void clearBrowser(WebBrowser browser) {
        browser.clearCache();
        browser.clearHistory();
        browser.clearRemoveCookies();
    }
}

我能看到的唯一缺点是 Java 中没有依赖于参数的查找,因此调用该方法会稍微冗长一些。

WebBrowserStuff.clearBrowser(browser);

我的问题是,考虑到在 C++ 中使用非成员函数是可取的(请参阅我的免责声明),除了增加冗长之外,还有什么理由不希望在 Java 中这样做?这个问题特别是关于 C++ 和 Java 在这种技术方面的区别。

不想听听个人关于这是否是一个好的面向对象设计的意见,尽管我兴趣听听 C++ 和 Java 之间是否存在任何可能导致普遍意见偏向于一种或另一种的文化差异。

[编辑]

不幸的是,我并没有真正得到我的问题的答案,我试图减少基于意见的编辑并没有阻止它被关闭,所以我无法选择一个可接受的答案。可以将其解释为实际上没有技术原因您不想这样做(假设这是 C++ 中的良好实践),并且对这种技术的任何反对纯粹是个人的或文化的 Java 事物。

4

3 回答 3

2
WebBrowserStuff.clearBrowser(browser);

是每个类定义的静态方法,并且不能直接访问所传递的实例之外的实例。出于实用性的原因,这需要另一个类。通常在 Java 的库本身中,只有当我们使用无法处理所有这些静态方法的专用类型(Array对象与Arrays类中的实用程序相比,或者Collections我们正在使用广泛的集合时)才会这样做。不应该采用静态方法的接口。

这些帮助程序类通常不是好的做法,在您的情况下,您可以并且应该将.clearBrowserWebBrowser

现在,这已经完成了,虽然这不是一个很好的做法,但它在技术上是有效的,并且没有任何合同义务拒绝你这项权利。在那一点上,为了满足 Java 库的命名,我将调用帮助类WebBrowsers,因为库通常采用有问题的类/接口并将其复数用于此命名目的。

于 2013-07-16T13:28:18.547 回答
1

可以接受,是的。首选,没有。原因如下:静态方法在本质上被排除在实例化的开销之外 - 所以为 WebBrowser 类上的一些支持方法创建一个新类是非常愚蠢的。如果有的话,将静态方法添加到 WebBrowser 类。这避免了您正在谈论的冗长,并将类似的事情放在一起。但是,我也同意 Colin 的观点,如果您将其构建为一种类型的库或稍后要扩展的东西 - 那么不要在一开始就过度隐藏东西。

于 2013-07-16T13:32:38.573 回答
0

不,这在 Java 中并不常见,也不是这样做的方式。您创建的 WebBrowserStuff 在 Java 中看起来像是单例模式的糟糕实现。您的实现的一个问题是您可以创建多个 WebBrowserStuff 实例。似乎您只需要一个,因此您应该使用Singleton

想想你是否想在浏览器中使用这些方法。在您的情况下,这似乎是正确的方法。它们应该是浏览器的一部分。

但是,如果你想创建一个辅助类,请确保将其设为 Singleton:添加一个私有构造函数,这样除了该类之外没有人可以创建实例并添加一个 getInstance() 方法来获取该实例。

于 2013-07-16T13:50:12.193 回答