更喜欢非成员非好友函数..在Java中

Prefer non-member non-friend functions... in Java?

本文关键字:Java 好友 成员 更喜欢 函数      更新时间:2023-10-16

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

在Java中,全局函数并不存在,起初这个原则似乎不适用,但在我看来确实适用。以Scott Meyers自己的例子为例。

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

通过创建一个包含静态便利方法的关联"namespace"类,我通过最小化可以访问其内部的代码量来增加了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的事情。

WebBrowserStuff.clearBrowser(browser);

是一个按类定义的静态方法,除了传递的实例之外,它不能直接访问实例。由于实用性原因,这需要另一个类。通常,在Java的库中,只有当我们使用无法处理所有这些静态方法的专用类型(与Arrays类中的实用程序形成对比的Array对象)或Collections时,才能实现这一点

这些辅助类通常不是很好的实践,在您的情况下,您可以并且应该clearBrowser作为WebBrowser的非静态方法。

现在,这已经完成了,虽然这不是一个很好的做法,但它在技术上是有效的,没有任何合同义务剥夺你的这一权利。注意,为了满足Java库的命名,我会调用助手类WebBrowsers,因为库通常会接受有问题的类/接口,并为此命名将其复数化。

可接受,是。首选,不。原因如下:静态方法本质上被排除在实例化时的开销之外——所以只为WebBrowser类上的一些支持方法创建一个新类是非常愚蠢的。如果有任何内容,请将静态方法添加到WebBrowser类中。这样可以避免你所说的冗长,并将相似的东西保持在一起。然而,我也同意科林的观点,如果你把它作为一种图书馆或以后要扩展的东西来构建,那么一开始就不要过度隐藏。

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

想一想,如果你想在浏览器中拥有这些方法。这似乎是处理你案件的正确方式。它们应该是浏览器的一部分。

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