[英]How to organize code logically into package while preserving encapsulation
This is a conceptual question.这是一个概念性的问题。
I usually organize code in packages logically.我通常按逻辑组织包中的代码。 Eg: math operation goes in
my.package.math
or business logic goes into my.package.business
and so on.例如:数学运算进入
my.package.math
或业务逻辑进入my.package.business
等等。
In these days I have a doubt that I want to share about a constraint imposed by the package visibility in java.在这些日子里,我怀疑我想分享 java 中包可见性强加的约束。
Let me show some code to explain better my case: I have the following package structure:让我展示一些代码来更好地解释我的情况:我有以下包结构:
+-- org.example
+-- greetings
| +-- RandomGreetings
+-- GreetingsService
|
+-- Main
and the following code:以及以下代码:
GreetingsService.java问候服务.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";
}
}
Main.java主程序
package org.example;
public class Main {
public static void main(String[] args) {
GreetingsService sayHelloService = new GreetingsService();
System.out.println(sayHelloService.greetingsToTheWorld());
}
}
This code, as I show you, doesn't compile because the class RandomGreetings
is package visible that means that GreetingsService can't instantiate it.正如我向您展示的,这段代码无法编译,因为
RandomGreetings
类是包可见的,这意味着 GreetingsService 无法实例化它。 This problem can be solved put public in the class RandomGreetings
:这个问题可以通过将public放在
RandomGreetings
类中来解决:
public class GreetingsService {
...
}
But RandomGreetings
for me is an implementation that I want to keep encapsulation and not public visible.但是
RandomGreetings
对我来说是一个实现,我想保持封装而不是公开可见。 In this scenario, the world (anyone that import the jar artifact the I may produce) is able to see and call that class and that is not something that I want.在这种情况下,世界(任何导入我可能生成的 jar 工件的人)都能够看到并调用该类,这不是我想要的。
Another possible solution is to move GreetingsService
at the same level of RandomGreetings, like so:另一种可能的解决方案是将
GreetingsService
移动到 RandomGreetings 的同一级别,如下所示:
+-- org.example
+-- greetings
| +-- RandomGreetings
| |
| +-- GreetingsService
|
+-- Main
In this case, the code compiles successfully and the RandomGreetings
is encapsulated but I end up with another problem for me.在这种情况下,代码编译成功并且
RandomGreetings
被封装,但我最终RandomGreetings
了另一个问题。
I not more able to organize that class in the package in a logical order.我无法按逻辑顺序在包中组织该类。
In this case, there are a few class so the situation is still manageable but if the number of class increase there will be only a unique big package I think.在这种情况下,有几个类,所以情况仍然可以管理,但是如果类的数量增加,我认为只会有一个独特的大包。
I know that in Java there is not subpackage visibility , so how do you manage that situation?我知道在 Java 中没有子包可见性,那么您如何管理这种情况?
How do you would solve the problem of my code above?你将如何解决我上面代码的问题?
When you want to use a package, it must have some entry point, which has to be public
.当你想使用一个包时,它必须有一些入口点,必须是
public
。 Otherwise you can throw the package away since it can't be used.否则,您可以将包裹扔掉,因为它无法使用。 This means your
org.example.greetings
package must have something, that is public
and can be used/called from "outside".这意味着你的
org.example.greetings
包必须有一些东西,那就是public
,可以从“外部”使用/调用。 It doesn't have to be your RandomGreetings
class.它不必是您的
RandomGreetings
类。
You can define an interface (in the org.example
package), implement it in your RandomGreetings
class and use another public
method to create and return the "package visible" RandomGreetings
class.您可以定义一个接口(在
org.example
包中),在您的RandomGreetings
类中实现它,并使用另一个public
方法来创建和返回“包可见”的RandomGreetings
类。 The code might look like this:代码可能如下所示:
package org.example;
public interface Greeting {
public String say();
}
This gets implemented by the RandomGreetings
class:这由
RandomGreetings
类实现:
package org.example.greetings;
import org.example.Greeting;
class RandomGreetings implements Greeting {
// ...
}
Then you define a public
helper class to return a RandomGreetings
object from the org.example.greetings
package:然后你定义一个
public
帮助类来从org.example.greetings
包中返回一个RandomGreetings
对象:
package org.example.greetings;
import org.example.Greeting;
public GeneratorHelper {
public static Greeting buildIt() {
return new RandomGreetings();
}
}
When you use the GeneratorHelper.buildIt()
method you get some object that implements the Greeting
interface.当您使用
GeneratorHelper.buildIt()
方法时,您将获得一些实现Greeting
接口的对象。 But you cannot access the RandomGreetings
class itself because it is still "package visible".但是您不能访问
RandomGreetings
类本身,因为它仍然是“包可见的”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.