封装与工厂模式在java中天然互补:封装通过私有构造器阻止外部直接实例化,工厂通过返回抽象类型隐藏具体实现,二者协同实现创建细节、内部状态和初始化逻辑的全面隐藏。

封装和工厂模式在 Java 中天然互补:封装负责“不让外部碰内部”,工厂模式负责“不让外部管怎么造”。二者结合,能彻底隐藏对象的创建细节和内部状态,让调用方只关注“做什么”,不关心“怎么做”和“长什么样”。
用私有构造器堵住直接 new 的路
这是配合的第一步。把类的构造方法设为 private,外部代码就无法用 new ProductA() 直接实例化。这样强制所有对象必须通过工厂获取,为后续控制留出空间。
常见写法:
- 具体产品类(如
FileLogger)声明private FileLogger() {} - 若该类本就不该被外部构造(比如只是日志实现),私有构造器就是默认防线
- 搭配静态工厂方法或具体工厂类使用,形成统一入口
工厂类只暴露接口,不暴露实现
工厂返回的是抽象类型(接口或抽象类),而不是具体类名。调用方拿到的是 Logger,不是 FileLogger;是 Product,不是 ProductA。这就把实现类完全藏在了背后。
例如:
-
LoggerFactory.createLogger()返回Logger接口 - 客户端只调用
logger.writeLog(),根本不知道底层是写文件还是连数据库 - 后续替换实现(比如从
FileLogger换成CloudLogger)只需改工厂内部,调用方零改动
把参数校验和初始化逻辑收进工厂
封装不只是藏字段,更要藏“怎么准备这个对象”。如果一个类需要复杂参数、依赖注入、资源预加载(比如连接池、配置解析),这些都不该暴露给使用者。
工厂承担这部分职责:
- 在
createCalculator()里自动读取配置、设置精度、初始化缓存 - 在
createDatabaseConnection()中完成 URL 解析、用户名密码解密、连接测试 - 调用方传入的可能只是一个简化的标识符(如
"prod"或ConfigType.HIGH_AVAILABILITY),其余全由工厂补全
配合不可变设计,强化封装效果
工厂返回的对象本身也应体现封装原则。比如返回一个 record 或 final 类型的 DTO,字段只读、无 setter,构造即完成全部校验与赋值。
这样整个链条就闭环了:
- 外部不能 new —— 构造器私有
- 外部不知道具体类型 —— 工厂返回接口
- 外部不参与初始化 —— 工厂封装参数处理
- 外部不能乱改状态 —— 返回对象不可变
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











