java - 这是使用 "default"Java 访问对客户端隐藏类和方法的好做法吗

标签 java oop access-modifiers

  • 对于类:

如果我们使用工厂方法,我们必须将创建的实现作为已实现接口(interface)的类型返回。

public class Factory {

  public Product getProduct() {
    return new ProductA();
  }
}

public interface Product {
}

class ProductA implements Product {
}

为了避免客户端将返回的产品转换为产品的具体实现{A、B、C...等},我们必须:

  1. 分别打包客户端和工厂的代码(比如com.example.clientcom.example.factory)
  2. 声明具有默认(“包”)访问权限的具体实现(对工厂可见,对客户端不可见)

    package com.example.client;
    ...
    public class Client {
      public static void main(String[] args) {
        Product i = new Factory().getProduct();
        ProductA a = (ProductA) i; // the type of ProductA isn't visible.
      }
    }
  • 对于方法:

例如我们需要使用隐藏方法的同一个工厂

public class Factory {

  public Product getProduct() {
    return new ProductA();
  }

  Product[] getCreatedProducts() {
    ...
  }
}

我在这里看到两个问题:

  • 错误的包结构:隐藏的类和方法必须与调用代码位于同一个包中。
  • 糟糕的代码:缺乏直观性和可理解性。将 java 文件替换为另一个包很容易中断。

最佳答案

“默认”访问并不能保证任何事情,因为任何流氓程序员都可以在您的包中声明他们的类。此外,无论您的包结构如何,在 Java 中,您几乎总是可以进行“实例”检查,然后向下转换为“实例”类型。因此,如果您的目标是防止任何向下转换,则必须使用 private 关键字。例如,您可以将 Product 接口(interface)的具体实现声明为 private static 或作为 Factory 中的匿名内部类。事实上,在 Bloch 的“如何设计一个好的 API”一文中,他提出了一个观点,即您应该“最小化所有内容的可访问性”。

也就是说,我认为您在这里有点偏执。如果有人沮丧,对你来说真的那么重要吗?您编写的任何代码都可能被滥用,当然,如果您包含一个文档齐全的工厂,那么您已经提供了有关如何正确使用 API 的明确信息。此外,如果您构建一个真正的工厂方法,它接受参数并具有明确的方法名称,而不是这个不接受参数的玩具 Factory 示例,那么我认为您会发现您正在广播正在创建的内容的公开相关部分。

关于java - 这是使用 "default"Java 访问对客户端隐藏类和方法的好做法吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6775894/

相关文章:

java - applicationContext是如何加载的?

java - 在 Java 中使用非空白字符时 split 方法如何工作?

c# - 如何使用 MVP 中的模型填充数据 GridView

delphi - 如何在不滚动到顶部的情况下查看函数或过程是私有(private)的、 protected 还是公共(public)的

c# - C# 中 "internal"关键字的实际用途

java - 从测试期间抛出的异常中获取自定义属性

java .wav 多次播放后播放失败

oop - 面向对象分析与现实生活中的 OOP 差异

c++ - 每个派生类的静态变量

java - 给定一个可变类,如何使这个类的特定对象不可变?