java - 打破一个类,或者强加一个接口(interface)来限制访问?

标签 java interface encapsulation

当不同类需要以不同方式从外部访问类的功能时,对类进行分区的最佳方法是什么?希望下面的例子能让问题清楚:)

我有一个 Java 类,它访问目录中的单个位置,允许外部类对其执行读/写操作。读取操作返回目录的使用情况统计信息(例如可用磁盘空间、写入次数等);显然,写操作允许外部类将数据写入磁盘。这些方法始终在同一位置工作,并从外部源(传递给构造函数)接收其配置(例如使用哪个目录、最小磁盘空间等)。

这个类看起来像这样:

public class DiskHandler {
    public DiskHandler(String dir, int minSpace) {
        ...
    }
    public void writeToDisk(String contents, String filename) {
        int space = getAvailableSpace();
        ...
    }
    public void getAvailableSpace() {
        ...
    }
}

还有很多事情要做,但这就足够了。

这个类需要由两个外部类以不同的方式访问。一个类需要访问读操作;另一个需要访问读取和写入操作。

public class DiskWriter {
    DiskHandler diskHandler;

    public DiskWriter() {
        diskHandler = new DiskHandler(...);
    }
    public void doSomething() {
        diskHandler.writeToDisk(...);
    }
}

public class DiskReader {
    DiskHandler diskHandler;

    public DiskReader() {
        diskHandler = new DiskHandler(...);
    }
    public void doSomething() {
       int space = diskHandler.getAvailableSpace(...);
    }    
}

此时,两个类共享同一个类,但只应读取的类可以访问写入方法。

解决方案1

我可以把这个类(class)分成两部分。一个类将处理读取操作,另一个类将处理写入操作:

// NEW "UTILITY" CLASSES
public class WriterUtil {
    private ReaderUtil diskReader;

    public WriterUtil(String dir, int minSpace) {
        ...
        diskReader = new ReaderUtil(dir, minSpace);
    }
    public void writeToDisk(String contents, String filename) {
        int = diskReader.getAvailableSpace();
        ...
    }
}
public class ReaderUtil {
    public ReaderUtil(String dir, int minSpace) {
        ...
    }
    public void getAvailableSpace() {
        ...
    }
}

// MODIFIED EXTERNALLY-ACCESSING CLASSES
public class DiskWriter {
    WriterUtil diskWriter;

    public DiskWriter() {
        diskWriter = new WriterUtil(...);
    }
    public void doSomething() {
        diskWriter.writeToDisk(...);
    }
}

public class DiskReader {
    ReaderUtil diskReader;

    public DiskReader() {
        diskReader = new ReaderUtil(...);
    }
    public void doSomething() {
       int space = diskReader.getAvailableSpace(...);
    }    
}

此解决方案可防止类访问不应访问的方法,但它也会破坏封装。原始的 DiskHandler 类是完全独立的,只需要通过单个构造函数配置参数。通过将功能分解为读/写类,它们都与目录有关,并且都需要使用各自的值进行实例化。本质上,我真的不想重复这些担忧。

解决方案2

我可以实现一个仅提供读取操作的接口(interface),并在类仅需要访问这些方法时使用它。

界面可能看起来像这样:

public interface Readable {
    int getAvailableSpace();
}

Reader 类将像这样实例化该对象:

Readable diskReader;
public DiskReader() {
    diskReader = new DiskHandler(...);
}

这个解决方案看起来很脆弱,并且将来很容易出现困惑。它不能保证开发人员将来会使用正确的接口(interface)。对 DiskHandler 实现的任何更改也可能需要更新接口(interface)以及访问类。我比以前的解决方案更喜欢它,但也不是很多。

坦率地说,这两种解决方案似乎都不完美,但我不确定是否应该优先选择其中一种。我真的不想破坏原来的类,但我也不知道从长远来看这个界面是否能给我带来很多好处。

我还缺少其他解决方案吗?

最佳答案

我会选择界面,并结合一点Dependency Injection - 你没有实例化 new DiskHandler直接在您的 reader 或 writer 类中,它们在其构造函数中接受适当类型的对象。

所以你的DiskReader会接受 Readable ,还有你的DiskWriter会得到 ReadWrite (或者直接 DiskHandler ,如果您不想为读写模式创建接口(interface),尽管我建议否则 - 通过 interface ReadWrite extends Readable 或类似的)。如果您始终使用适当的接口(interface)注入(inject)它,则不必担心使用不正确。

关于java - 打破一个类,或者强加一个接口(interface)来限制访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2900868/

相关文章:

typescript - 属性 X 的类型不兼容

c# - C# 中的实现差异

java - 保存和查看数据时的时区

java - 前缀和后缀运算符java

Java 原语和原语包装器

c++ - %Python 接口(interface)的 C++ 库的类型映射

java - 获取包含的 jar 的 NoClassDefFoundError

oop - 理解封装和抽象的简单方法

api - 模拟每个领域或好的 api

java - 使用传递给构造函数的引用是否可以安全 - Java