写在前面
Hello,我是易元,这篇文章是我学习设计模式时的笔记和心得体会。如果其中有错误,欢迎大家留言指正!
初版注册功能
那时的UserService
还是个清爽少年,只需两步走天下。然而,命运的齿轮开始转动......
java
// 初版代码:简单却纯粹的协作
public class UserService {
private UserDao userDao = new UserDao();
private EmailService emailService = new EmailService();
public void register(String username) {
userDao.save(username); // 数据库:用户已入库!
emailService.sendWelcomeEmail(username); // 邮件:叮!您的专属拉花已送达~
}
}
EmailService
typescript
public class EmailService {
public void sendWelcomeEmail(String username) {
System.out.println("发送欢迎邮件给: " + username);
}
}
UserDao
typescript
public class UserDao {
public void save(String userName) {
System.out.println("用户: " + userName + "已保存到数据库");
}
}
需求风暴的暴击
产品经理
带着新需求闪现
:客户超爱邮件功能!但还要加短信通知、送200积分!明天上线!
小易的屏幕疯狂闪烁,手指在键盘上舞成残影:
PointsService
typescript
public class PointsService {
public void addWelcomePoints(String username) {
System.out.println("增加新人积分(200): " + username);
}
}
SmsService
typescript
public class SmsService {
public void sendRegisterSms(String username) {
System.out.println("向: " + username + "发送注册短信");
}
}
UserService被迫"身兼数职"
java
public class UserService {
private UserDao userDao = new UserDao();
private EmailService emailService = new EmailService();
private SmsService smsService = new SmsService();
private PointsService pointsService = new PointsService();
public void register(String username) {
userDao.save(username); // 存用户
emailService.sendWelcomeEmail(username); // 发邮件
smsService.sendRegisterSms(username); // 发短信
pointsService.addWelcomePoints(username); // 送积分
// UserService:我裂开了.jpg
}
}
凌晨的办公室回荡着键盘的悲鸣,突然传来窸窸窣窣的对话
UserService :我明明是注册服务,为啥还要当快递员+会计?!这是哪个杀千刀的给我安排这么重的活儿!!
SmsService :老板说必须发短信验证!
PointsService:200积分!少一分都不行!
外观模式的重构
小易盯着屏幕上臃肿的UserService
,眉头拧成了死结。他翻开《设计模式之美》,指尖停在了外观模式的章节
设计精髓
-
核心思想:为子系统提供统一的高层接口
-
核心角色:
- Facade :
UserRegistrationFacade
(指挥全局的指挥官) - SubSystem :
UserDao
/EmailService
等(各司其职的士兵)
- Facade :
重构后的注册服务
子系统保持纯粹职责
typescript
public class EmailService {
public void sendWelcomeEmail(String username) {
System.out.println("发送欢迎邮件给: " + username);
}
}
public class PointsService {
public void addWelcomePoints(String username) {
System.out.println("为增加新人积分" + username);
}
}
UserRegistrationFacade(指挥官)
java
public class UserRegistrationFacade {
private UserDao userDao = new UserDao();
private EmailService emailService = new EmailService();
private SmsService smsService = new SmsService();
private PointsService pointsService = new PointsService();
public void completeRegistration(String username) {
userDao.save(username);
emailService.sendWelcomeEmail(username);
smsService.sendRegisterSms(username);
pointsService.addWelcomePoints(username);
}
}
UserService重归清爽
typescript
public class UserService {
private UserRegistrationFacade facade = new UserRegistrationFacade();
public void register(String username) {
System.out.println("业务逻辑处理");
facade.completeRegistration(username);
}
}
晨光透过百叶窗洒在屏幕上,UserService 轻轻哼唱:
「我还是从前那个少年,没有一丝丝改变~」
长话短说
核心价值
- 将多步操作封装为单一接口
- 业务逻辑与子系统交互解耦
- 统一管理调用顺序与异常
适用场景
- 系统存在多个交互复杂的子系统
- 需要降低客户端与子系统的耦合度
- 涉及多层调用或复杂初始化流程
- 要求统一权限管控或流程监控
实现四步曲
- 划定需要封装的子系统边界
- 创建外观类定义高层接口
- 编排执行顺序
- 客户端统一通过外观类交互
特别提示
- 避免打造"上帝外观",保持单一职责
- 可搭配工厂模式动态创建子系统
- 平衡封装力度,预留扩展入口