
本文介绍一种在java中组织多层类结构的方法:通过合理划分包、结合工厂模式,使主类能访问所有子类,而子类之间相互不可见,从而在保持封装性的同时满足模块化设计需求。
本文介绍一种在java中组织多层类结构的方法:通过合理划分包、结合工厂模式,使主类能访问所有子类,而子类之间相互不可见,从而在保持封装性的同时满足模块化设计需求。
在典型的面向对象Java项目中,当存在一个核心协调类(如 CoffeePlace)需使用多个逻辑分组的组件(如 Worker 和 Machine),而这些组件又不应彼此直接耦合时,简单的嵌套包结构(如 coffeeplace.worker.* 和 coffeeplace.machine.*)容易导致封装泄露——因为若所有具体类都声明为 public,则 IceCreamMachine 就能意外访问 BaristaWorker 的方法,违背单一职责与高内聚低耦合原则。
解决这一问题的关键在于限制具体实现类的可见性范围,并将对象创建权交由受控的工厂类。以下是推荐的实践方案:
✅ 正确的包与可见性设计
coffeeplace/
├── CoffeePlace.java // public class —— 唯一对外暴露的入口
├── worker/
│ ├── AbstractWorker.java // public abstract class
│ ├── WorkerFactory.java // public class —— 仅此工厂可访问具体Worker
│ ├── AbstractWorkerImpl.java // package-private(默认访问修饰符)
│ ├── BaristaWorker.java // package-private
│ ├── DishWasherWorker.java // package-private
│ └── CashierWorker.java // package-private
└── machine/
├── AbstractMachine.java // public abstract class
├── MachineFactory.java // public class —— 仅此工厂可访问具体Machine
├── AbstractMachineImpl.java // package-private
├── CoffeeMachine.java // package-private
├── OrangeJuiceMachine.java // package-private
└── IceCreamMachine.java // package-private
? 关键点:所有具体实现类(如
BaristaWorker、CoffeeMachine)不加public修饰符,仅在各自包内可见;抽象基类和工厂类声明为public,但工厂内部通过包级访问调用私有实现。
Alibabacloud Sdk Client Initialization For Java下载在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
✅ 工厂模式实现示例
// coffeeplace/machine/MachineFactory.java
package coffeeplace.machine;
public class MachineFactory {
public static AbstractMachine createCoffeeMachine() {
return new CoffeeMachine(); // ✅ 合法:同包访问
}
public static AbstractMachine createOrangeJuiceMachine() {
return new OrangeJuiceMachine();
}
// 其他创建方法...
}
// coffeeplace/CoffeePlace.java
package coffeeplace;
import coffeeplace.machine.AbstractMachine;
import coffeeplace.machine.MachineFactory;
import coffeeplace.worker.AbstractWorker;
import coffeeplace.worker.WorkerFactory;
public class CoffeePlace {
private final List<abstractworker> workers = new ArrayList();
private final List<abstractmachine> machines = new ArrayList();
public CoffeePlace() {
// ✅ 仅依赖抽象类型与工厂,不感知具体实现
workers.add(WorkerFactory.createBarista());
workers.add(WorkerFactory.createDishWasher());
machines.add(MachineFactory.createCoffeeMachine());
machines.add(MachineFactory.createOrangeJuiceMachine());
}
// 业务逻辑中只调用 AbstractWorker.doWork() / AbstractMachine.operate()
}</abstractmachine></abstractworker>
⚠️ 注意事项与进阶建议
-
不可跨包访问:
machine包中的类无法实例化worker包内的具体类(如BaristaWorker),反之亦然——这正是包级封装的核心保障; -
避免过度抽象:若
CoffeePlace频繁需要向下转型(如(CoffeeMachine) machine.startBoiler()),说明AbstractMachine接口设计不足,应重构接口或引入策略/组件模式; - 替代方案参考:对于高度动态、可组合的系统(如模拟器或游戏引擎),可考虑 Entity-Component-System(ECS) 架构,以组合代替继承,进一步解耦行为与数据;
-
构建工具友好:该结构天然适配 Maven/Gradle 的标准目录布局(
src/main/java/coffeeplace/...),无需额外配置。
综上,通过“抽象类 + 工厂 + 包级私有实现”的三层设计,既满足了主类对全量组件的统一调度需求,又严格守住了封装边界——不是所有 public 类都需要被全局看见,可见性控制,才是面向对象设计真正的第一道防线。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











