我正在开发一个具有这种结构的机器人程序(我将包括这些层的作用只是为了笑):
A 层 - GUI 用于处理按钮、操纵杆等的简单界面。将这些值转换为命令以发送到控制界面。
B 层 - 控制评估来自数据库的设备读取/写入条目和来自 gui 的命令请求,以便为数据库计算新的设备写入条目
C 层 - 数据库 设备的逻辑表示,创建从设备写入和读取的值的历史记录
D 层 - 硬件与物理硬件对话。将设备写入条目翻译成命令并将它们发送到设备。使用来自设备的值更新数据库设备读取条目。
我想创建一个 Java 应用程序,其中任何层都无法调用其上方或下方多于一层的函数。
是否可以使用包隐私或类似工厂的模式来创建项目结构,这使得代码无法进入,比如说层 A,从层 D 或 C 导入任何东西?
最佳答案
TL;DR 对此没有单一的 Elixir 解决方案,但可以利用许多不同的工具
有多种不同的技术可以隔离软件应用程序的不同部分,但我认为没有任何一种解决方案可以解决所有问题。一些构建系统可以限制目标之间的依赖关系(例如 Bazel 在构建目标上有一个 visibility
属性,可以防止一个目标依赖另一个目标,即使它们通过 Java 的类可见性彼此可见) 可以与 Java 的内置可见性结合使用。例如:
// Foo.java
package com.yourcompany.foo;
public class Foo {}
// Build rule for Foo.java
java_library(
name = "Foo",
srcs = ["Foo.java"],
# Restricts visibility to this directory, even though
# the class visibility was "public"
visibility = ["//visibility:private"],
)
// Bar.java
package com.yourcompany.bar;
import com.yourcompany.foo.Bar; // prevented by build visibility system
public class Bar {
Foo foo = new Foo();
}
也可以使用接口(interface)来调解逻辑组件之间的所有交互并隐藏这些接口(interface)的实现(例如,仅通过服务注册接口(interface)或通过接口(interface)依赖注入(inject)公开实现)。例如,使用 Dagger , 你可以创建一个单独的 component对于每一层,这将允许您编写如下代码:
final class ControllerImpl implements Controller {
// Since "ControllerImpl" is instantiated / wired into the
// controller layer, the database dependency is available /
// exposed for injection within this layer. The access control is
// strictly performed by the way the dependencies are wired.
@Inject
public ControllerImpl(Database database) {
// ...
}
}
除上述之外,您还可以使用依赖分析/依赖分析测试或提交 Hook 来自动检测依赖规则违规(并根据它们触发错误/拒绝提交)。例如,穷人的解决方案是简单地扫描每个文件的包声明和导入语句,然后使用一些试探法来检测错误的依赖项。
另一种方法是将不同的组件捆绑在单独的 JAR 中,并使用自定义的 ClassLoader 加载它们。 ,这将允许您使用反射防止非法访问(否则可能会绕过任何程序结构)。
除了自动化方法,手动方法也有其值(value)。手动方法包括定期代码审查和在这些代码审查和审计期间强制执行的政策。
简而言之,没有一个正确答案。有必要结合使用几种不同的方法,具体取决于这种分离的重要性。
关于java - 在大型程序中管理隐私,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31496994/