gpt4 book ai didi

java - 如何在保留封装的同时将代码逻辑地组织到包中

转载 作者:行者123 更新时间:2023-11-30 10:03:48 25 4
gpt4 key购买 nike

这是一道概念题。
我通常在逻辑上组织包中的代码。例如:数学运算进入 my.package.math 或业务逻辑进入 my.package.business 等等。

这些天我有一个疑问,我想分享一个由 java 中的包可见性强加的约束。

让我展示一些代码来更好地解释我的情况:我有以下包结构:

+-- org.example
+-- greetings
| +-- RandomGreetings
+-- GreetingsService
|
+-- Main

和下面的代码:

GreetingsService.java

package org.example;

import org.example.greetings.RandomGreetings;

public class GreetingsService {
public String greetingsToTheWorld(){
RandomGreetings greetings = new RandomGreetings();
return greetings.say() + " World";
}
}

RandomGreetings.java

package org.example.greetings;

import java.util.Random;

class RandomGreetings {
public String say() {
Random rand = new Random();
int value = rand.nextInt(2);
return value==0 ? "Hello" : "Hi";
}
}

主.java

package org.example;

public class Main {

public static void main(String[] args) {
GreetingsService sayHelloService = new GreetingsService();
System.out.println(sayHelloService.greetingsToTheWorld());
}
}

正如我向您展示的,此代码无法编译,因为类 RandomGreetings 是包可见的,这意味着 GreetingsService 无法实例化它。这个问题可以通过将 public 放在类 RandomGreetings 中来解决:

public class GreetingsService {
...
}

但是 RandomGreetings 对我来说是一个我想保持封装而不是公开可见的实现。在这种情况下,世界(任何导入我可能生成的 jar 工件的人)都能够看到并调用该类,而这不是我想要的。

另一种可能的解决方案是将 GreetingsService 移动到与 RandomGreetings 相同的级别,如下所示:

+-- org.example
+-- greetings
| +-- RandomGreetings
| |
| +-- GreetingsService
|
+-- Main

在这种情况下,代码编译成功,RandomGreetings 被封装,但我遇到了另一个问题。
我无法按逻辑顺序在包中组织该类。
在这种情况下,有几个类,所以情况仍然可以控制,但如果类的数量增加,我认为只会有一个独特的大包。

我知道在 Java 中没有 subpackage visibility ,那么您如何处理这种情况?
你会如何解决我上面的代码的问题?

最佳答案

当你想使用一个包时,它必须有一些入口点,它必须是public。否则您可以将包裹扔掉,因为它无法使用。这意味着您的 org.example.greetings 包必须有一些东西,即 public 并且可以从“外部”使用/调用。它不一定是您的 RandomGreetings 类。

您可以定义一个接口(interface)(在 org.example 包中),在您的 RandomGreetings 类中实现它并使用另一个 public 方法来创建并返回“包可见”RandomGreetings 类。代码可能如下所示:

package org.example;

public interface Greeting {
public String say();
}

这由 RandomGreetings 类实现:

package org.example.greetings;

import org.example.Greeting;

class RandomGreetings implements Greeting {
// ...
}

然后定义一个 public 帮助类,从 org.example.greetings 包中返回一个 RandomGreetings 对象:

package org.example.greetings;

import org.example.Greeting;

public GeneratorHelper {
public static Greeting buildIt() {
return new RandomGreetings();
}
}

当您使用GeneratorHelper.buildIt() 方法时,您会得到一些实现了Greeting 接口(interface)的对象。但是您不能访问 RandomGreetings 类本身,因为它仍然是“包可见的”。

关于java - 如何在保留封装的同时将代码逻辑地组织到包中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56200895/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com