登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
每日签到
每天签到奖励2圆-6圆
发帖说明
VIP申请
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
写记录
写博客
VIP申请
VIP网盘
网盘
联系我们
每日签到
道具
勋章
任务
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
业界
›
「全网最细 + 实战源码案例」设计模式——外观模式 ...
「全网最细 + 实战源码案例」设计模式——外观模式
[ 复制链接 ]
户烫擞
2025-6-6 14:13:54
概念
外观模式是一种结构型模式,
为复杂的子系统提供一个统一的接口
,使得子系统的功能
对外界更加简单、易用。
与真实世界的类比
当你通过打电话给商店下达订单时,接线员就是该商店所有服务和部门的
外观。
接线员为你提供了一个包含购物系统、支付网关、送货等服务的简单语言
接口
。
外观模式结构图
// 空调
public class AirCondition {
public void on() {
System.out.println("AirCondition is on");
}
public void off() {
System.out.println("AirCondition is off");
}
}
复制代码
// 灯
public class Light {
public void on() {
System.out.println("Light is on");
}
public void off() {
System.out.println("Light is off");
}
}
复制代码
// 电视
public class TV {
public void on() {
System.out.println("TV on");
}
public void off() {
System.out.println("TV off");
}
}
复制代码
// 外观类,封装了子系统的功能
public class SmartAppliancesFacade {
private TV tv;
private AirCondition airCondition;
private Light light;
public SmartAppliancesFacade() {
tv = new TV();
airCondition = new AirCondition();
light = new Light();
}
public void say(String message){
if(message.contains("打开")){
allOn();
}else if(message.contains("关闭")){
allOff();
}else{
System.out.println("没有这个指令");
}
}
public void allOn() {
tv.on();
airCondition.on();
light.on();
}
public void allOff() {
tv.off();
airCondition.off();
light.off();
}
}
复制代码
// 客户端类
public class Client {
public static void main(String[] args) {
SmartAppliancesFacade facade = new SmartAppliancesFacade();
facade.say("打开家电");
System.out.println("-----------------------------------------");
facade.say("关闭家电");
System.out.println("-----------------------------------------");
facade.say("shfsahf");
System.out.println("-----------------------------------------");
}
}
复制代码
适用的应用场景
简化复杂系统:
如果一个系统由多个模块组成,对外提供多个复杂接口,可以通过外观模式提供一个简单的接口调用。
例如:支付系统涉及签名、网络请求、结果处理,通过 Facade Pattern 封装为一个简单的支付接口。
分层架构设计:
在分层系统种,可以在子系统的每一层使用 Facade Pattern ,减少高层模块对低层模块的依赖。
对遗留系统的封装:
当需要对已有系统添加新的功能或优化时,但不想破坏原有设计,可以通过 Facade Pattern 封装已有系统,提供新的接口。
优点
降低客户端与子系统的
耦合
:
Client 无需了解 Subsystem 的具体实现。
提高子系统的
灵活性
:
Subsystem 可以在不影响 Client 的情况下自由修改。
提高可
维护性
:
Subsystem 的接口变化只需要修改 Facade,而不需要修改 Client 代码
缺点
外观类可能会成为
上帝对象
(了解过多或者负责过多的对象)
在一定程度上
违反开闭原则
,子系统添加新功能,可能需要修改外观类。
解决:
使用
抽象外观类
:将 Facade定义为一个 abstract class或 interface,提供基本的功能接口。每次扩展时,可以通过创建新的外观类来实现拓展,替代了直接修改原有的 Facade。
// 抽象外观类
public abstract class AbstractSmartHomeFacade {
public abstract void startMode();
public abstract void stopMode();
}
// 具体实现类
public class SmartHomeFacade extends AbstractSmartHomeFacade {
private Light light;
private SoundSystem soundSystem;
private AirConditioner airConditioner;
public SmartHomeFacade() {
this.light = new Light();
this.soundSystem = new SoundSystem();
this.airConditioner = new AirConditioner();
}
@Override
public void startMode() {
light.turnOn();
soundSystem.playMusic();
airConditioner.turnOn();
}
@Override
public void stopMode() {
light.turnOff();
soundSystem.stopMusic();
airConditioner.turnOff();
}
}
// 新增扩展外观类
public class AdvancedSmartHomeFacade extends SmartHomeFacade {
private Curtain curtain;
public AdvancedSmartHomeFacade() {
super();
this.curtain = new Curtain();
}
@Override
public void startMode() {
super.startMode();
curtain.close();
}
@Override
public void stopMode() {
super.stopMode();
curtain.open();
}
}
复制代码
使用
组合代替继承
:通过组合的方式,将新增的功能封装成独立的类,再将其组合进外观类,替代直接 Facade的代码。
public class SmartHomeFacade {
private List<Object> subsystems = new ArrayList<>();
public void addSubsystem(Object subsystem) {
subsystems.add(subsystem);
}
public void startAll() {
for (Object subsystem : subsystems) {
// 统一调用子系统的 start 方法
// 可以通过接口或反射实现
}
}
public void stopAll() {
for (Object subsystem : subsystems) {
// 统一调用子系统的 stop 方法
}
}
}
复制代码
public class Client {
public static void main(String[] args) {
// 创建外观类
SmartHomeFacade facade = new SmartHomeFacade();
// 添加子系统
facade.addSubsystem(new Light());
facade.addSubsystem(new SoundSystem());
facade.addSubsystem(new AirConditioner());
// 省略
// …………………………………………
// 启动所有子系统
System.out.println("Starting all subsystems...");
facade.startAll();
// 停止所有子系统
System.out.println("\nStopping all subsystems...");
facade.stopAll();
}
}
复制代码
案例实现
在源码中的应用——Tomcat
使用 Tomcat 作为 Web 容器时,Coyote 接受浏览器发送的请求,封装为 Request。为了符合 Servlet API 标准,Tomcat 使用 RequestFacade(实现了 HttpServletRequest接口)对内部的 Request对象进行包装。
所以,在 Servlet 中开发者接触到的 Request其实是 RequestFacade,通过 Facade 模式,隐藏了实现细节,确保安全性和封装性。
与其他设计模式的关系
外观模式为现有对象定义了一个新接口, 适配器模式则会试图运用已有的接口。
适配器
通常只封装一个对象,
外观
通常会作用于整个对象子系统上。
当只需对客户端代码隐藏子系统创建对象的方式时, 你可以使用抽象工厂模式来代替外观。
享元模式展示了如何生成大量的小型对象, 外观则展示了如何用一个对象来代表整个子系统。
外观和中介者模式的职责类似: 它们都尝试在大量紧密耦合的类中组织起合作。
外
观
为子系统中的所有对象定义了一个简单接口, 但是它不提供任何新功能。 子系统本身不会意识到外观的存在。 子系统中的对象可以直接进行交流。
中
介
者
将系统中组件的沟通行为中心化。 各组件只知道中介者对象, 无法直接相互交流。
外观类通常可以转换为单例模式类, 因为在大部分情况下一个外观对象就足够了。
外观与代理模式的相似之处在于它们都缓存了一个复杂实体并自行对其进行初始化。
代理
与其服务对象遵循同一接口, 使得自己和服务对象可以互换, 在这一点上它与
外观
不同。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
全网
最细
实战
源码
案例
相关帖子
Java集合框架实战应用指南
MySQL 字符串替换实战指南:2 个函数搞定 90% 业务需求
解密prompt系列60. Agent实战:从0搭建Jupter数据分析智能体
TypeScript 队列实战:从零实现简单、循环、双端、优先队列,附完整测试代码
社交app源码开发平台基础知识,软件二维码的生成
漏洞实战--java反序列化--用友NC UserAuthenticationServlet
JWT攻击详解与CTF实战
Tekla坐标定位插件源码
鸿蒙应用开发从入门到实战(二):DevEco Studio工具安装
从基础到实战:一文吃透 JS Tuples 与 Records 的所有核心用法
vip免费申请,1年只需15美金$
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
业界
Java集合框架实战应用指南
0
760
颛孙中
2025-09-02
业界
MySQL 字符串替换实战指南:2 个函数搞定 90% 业务需求
0
454
奸轲嫣
2025-09-05
业界
解密prompt系列60. Agent实战:从0搭建Jupter数据分析智能体
0
368
赊朗爆
2025-09-08
业界
TypeScript 队列实战:从零实现简单、循环、双端、优先队列,附完整测试代码
0
258
蓟晓彤
2025-09-09
安全
社交app源码开发平台基础知识,软件二维码的生成
0
584
慷规扣
2025-09-09
安全
漏洞实战--java反序列化--用友NC UserAuthenticationServlet
0
650
锦惺
2025-09-09
业界
JWT攻击详解与CTF实战
0
327
癖艺泣
2025-09-10
业界
Tekla坐标定位插件源码
0
254
慎气
2025-09-10
业界
鸿蒙应用开发从入门到实战(二):DevEco Studio工具安装
0
975
府扔影
2025-09-11
业界
从基础到实战:一文吃透 JS Tuples 与 Records 的所有核心用法
0
956
陆菊
2025-09-11
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
浏览过的版块
安全
签约作者
程序园优秀签约作者
发帖
户烫擞
2025-6-6 14:13:54
关注
0
粉丝关注
16
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
敖可
9984
杭环
9988
凶契帽
9988
4
氛疵
9988
5
黎瑞芝
9988
6
猷咎
9986
7
里豳朝
9986
8
肿圬后
9986
9
蝓俟佐
9984
10
虽裘侪
9984
查看更多