java - Java应用程序在初始化时返回超类
问题描述
现在我们正在编写一些核心应用程序,所有其他应用程序都将依赖这些应用程序。不用多说,让我用一些代码解释逻辑,
我们曾经有一个 1000 多行长的 java 文件,每个应用程序都将它作为类在里面,所以当发生变化时,每个应用程序都必须编辑其中的 java 文件,或者简单地修复一个并复制到所有. 这很难实现,也很难维护。然后我们最终将其创建为一个单独的应用程序,该应用程序被划分为更小的部分,易于维护,而且核心可能是对其他应用程序的依赖,因此我们在一个地方修复,所有其他代码应用程序也已修复。
一段时间以来,我一直在为此考虑一些很棒的结构,想为此使用构建器模式,如下所示
TheCore theCore = new TheCore().Builder()
.setSomething("params")
.setSomethingElse(true)
.build();
现在问题出现了。像这样,我初始化了对象,但现在我public
只能访问该对象类。这个应用程序实际上将有许多小类,它们具有public
我不希望它们成为每次都可以调用的静态方法的功能。TheCore
相反,我希望只有在类被初始化时才调用这些方法;
// doSomething() will be from another class
theCore.doSomething()
我产生了一些想法
someOtherClass.doSomething(theCore)
将主对象作为参数注入,但仍someOtherClass
需要初始化,甚至需要一个静态方法,这让我感觉不舒服,而且是正确的方法。
实际上,我不在乎初始化TheCore
是否会给我带来一个超级对象,该对象包含所有其他类在初始化并准备好在我初始化后访问TheCore
。我只希望在这个结构中拥有一个可维护的单独应用程序和可用的方法,前提是仅TheCore
初始化这种情况下的主要对象。
什么是实现它的正确方法?我看到Java不允许扩展多个类,即使这样做,我不确定这是正确的方式......
谢谢。
解决方案
在花费大量时间思考之后,我最终认为
// doSomething() will be from another class
theCore.doSomething()
不适合,因为许多 java 类可能具有相同的方法名称。所以...
// doSomething() will be from another class
theCore.someOtherClass.doSomething()
将是一个更好的方法。
为了更容易理解,我将不得不遵循一个复杂的路径来解释它,首先从包类开始。
认为我有一个名为的包Tools
和一个类SomeFancyTool
main
└─java
└─com
└─<domainName>
├─Tools
| └─SomeFancyTool.java
└─TheCore.java
现在这SomeFancyTool.java
必须有一个默认访问级别,实际上是包级别访问,因为我不希望直接访问这些类;
SomeFancyTool.java
package com.<domainName>.Tools
class SomeFancyTool{
public String someStringMethod(){
return "Some string!";
}
public int someIntMethod(){
return 123;
}
public boolean someBooleanMethod(){
return true;
}
}
所以现在我们有了这个SomeFancyTool.java
类,但TheCore.java
不能访问它,因为它Tools
只能通过它的包来访问。在这一点上,我想到了一个将在同一个包中的 Initializer 类,初始化这些私有类并在调用时用一个函数返回它们。所以初始化器类看起来像这样;
工具初始化器.java
package com.<domainName>.Tools
public class ToolsInitializer{
private SomeFancyTool someFancyTool = new SomeFancyTool();
public SomeFancyTool getSomeFancyTool(){
return someFancyTool;
}
}
由于ToolsInitializer.java
可以初始化Tools
包内的所有功能私有类,也可以将它们作为对象返回到包范围之外,因此我们仍然无法使用这些方法,因为我们无法使用这些方法,import com.<domainName>.SomeFancyTool
因为TheCore.java
它是包范围内可访问的。我认为在这里我们可以从 java 的实现中受益interface
。一个不是单独起作用的类,所以即使它被访问也没有问题,因为它的方法只不过是声明。
在这一点上,我将重命名SomeFancyTool.java
它将SomeFancyToolImplementation.java
实现interface
并调用SomeFancyTool.java
接口本身。
SomeFancyTool.java(现在作为接口)
package com.<domainName>.Tools
public interface SomeFancyTool{
public String someStringMethod();
public int someIntMethod();
public boolean someBooleanMethod();
}
并让我们先重命名SomeFancyTool.java
并实现interface
SomeFancyToolImplementation.java(重命名)
package com.<domainName>.Tools
class SomeFancyToolImplementation implements SomeFancyTool{
@override
public String someStringMethod(){
return "Some string!";
}
@override
public int someIntMethod(){
return 123;
}
@override
public boolean someBooleanMethod(){
return true;
}
}
现在我们的结构在最后的编辑中变成了这样;
main
└─java
└─com
└─<domainName>
├─Tools
| ├─SomeFancyTool.java
| ├─SomeFancyToolImplementation.java
| └─ToolsInitializer.java
└─TheCore.java
最后,我们可以使用我们的TheCore.java
类调用所有初始化类及其方法,以将所有这些私有类作为对象接收。这将允许外部应用程序首先调用和初始化TheCore
以便能够访问其他方法。
TheCore.java
public class TheCore{
private SomeFancyToolImplementation someFancyTool;
public static class Builder{
private SomeFancyToolImplementation someFancyTool;
public Builder(){
ToolsInitializer toolsInitializer = new ToolsInitializer();
someFancyTool = toolsInitializer.getSomeFancyTool();
}
public Builder setSomeValues(){
//some values that is needed.
return this;
}
public Builder setSomeMoreValues(){
//some values that is needed.
return this;
}
public TheCore build(){
TheCore theCore = new TheCore();
theCore.someFancyTool = someFancyTool;
return theCore;
}
}
}
全部完成,可以使用了。现在,它所依赖的功能包类及其方法是否TheCore
已初始化,无法通过 out 访问TheCore
。从 3rd 方应用程序中简单地使用这个库就是:
第 3 方应用程序
TheCore theCore = new TheCore.Builder()
.setSomeValues("Some Values")
.setMoreSomeValues("Some More Values")
.build();
theCore.someFancyTool.someStringMethod();
注意:请注意,aToolsInitializer.java
仍然可以访问,并且可以在不首先调用的情况下使用 get 私有方法,但是如果不满足某些先决条件,TheCore
我们总是可以在getSomeFancyTool()
方法内部设置一个检查器来出错。throw
我仍然不知道这是要使用的功能结构模式还是我的一些艰难的想法。并且不知道是否已经存在一些我还看不到的模式,但这是我最终得到的解决方案。
推荐阅读
- c# - OnOptionsItemSelected 发生 NavigationRoot 时不调用
- regex - 正则表达式:从路径中提取特定字符串
- php - 如何仅使用 php 创建wireguard 密钥?
- python - cvxpy -> OSQP 或 cvxpy -> CVXOPT 它是如何工作的?
- c# - Azure Kubernetes 服务并使用 c# 通过 smtp 发送邮件
- javascript - 避免 Angular 中的嵌套循环
- reactjs - 当您不知道路径时,在 gastby 中动态创建页面
- swift - 使用 == 比较 firebase 文档中的数据会给出协议 'Any',因为类型不能符合 'Equatable'
- php - 更改 php var 表单付款处理
- php - 为什么 nodejs 服务器会收到很多未知的 php/wordpress 请求?