诗曰:
子系统多太复杂,调用繁琐如乱麻。
外观模式来相助,如来神掌一指定。
📖 故事
话说师徒四人来到"万法归宗山",此地法术众多,调用繁琐。
唐僧愁道:"悟空,这施法要念的咒语太多,为师记不住啊!"
悟空笑道:"师父莫急!徒儿用外观模式,一招'如来神掌'搞定所有!"
🐉 踩坑打怪:调用繁琐之劫
第一劫:子系统太多
java
// 各种子系统
public class MantraChanting { // 念咒子系统
public void chantMantra(String mantra) {
System.out.println("念咒:" + mantra);
}
}
public class HandSeal { // 结印子系统
public void makeSeal(String seal) {
System.out.println("结印:" + seal);
}
}
public class QiCirculation { // 运功子系统
public void circulateQi(String meridian) {
System.out.println("运功:" + meridian);
}
}
public class TargetLock { // 锁定目标子系统
public void lockTarget(String target) {
System.out.println("锁定目标:" + target);
}
}
第二劫:调用太繁琐
java
// 没有外观模式,唐僧要这样施法
public class TangSeng {
public void castFireball(String target) {
// 1. 念咒
MantraChanting mantra = new MantraChanting();
mantra.chantMantra("唵嘛呢叭咪吽");
// 2. 结印
HandSeal handSeal = new HandSeal();
handSeal.makeSeal("火焰印");
// 3. 运功
QiCirculation qi = new QiCirculation();
qi.circulateQi("手少阴心经");
// 4. 锁定目标
TargetLock targetLock = new TargetLock();
targetLock.lockTarget(target);
// 5. 施法
System.out.println("发射火球!🔥");
}
public void castIceball(String target) {
// 类似的繁琐流程...
MantraChanting mantra = new MantraChanting();
mantra.chantMantra("唵嘛呢叭咪吽");
HandSeal handSeal = new HandSeal();
handSeal.makeSeal("寒冰印");
QiCirculation qi = new QiCirculation();
qi.circulateQi("手太阴肺经");
TargetLock targetLock = new TargetLock();
targetLock.lockTarget(target);
System.out.println("发射冰球!❄️");
}
}
八戒抱怨: "猴哥!每招法术都要写这么多代码,太麻烦了!"
悟空点头: "正是!俺老孙得整个'如来神掌',一键施法!"
⚔️ 外观模式大法
第一步:创建外观类
java
// 法术外观类
public class MagicFacade {
// 持有所有子系统的引用
private MantraChanting mantra;
private HandSeal handSeal;
private QiCirculation qi;
private TargetLock targetLock;
public MagicFacade() {
this.mantra = new MantraChanting();
this.handSeal = new HandSeal();
this.qi = new QiCirculation();
this.targetLock = new TargetLock();
}
// 简化后的施法方法
public void castFireball(String target) {
System.out.println("=== 如来神掌:火球术 ===");
mantra.chantMantra("唵嘛呢叭咪吽");
handSeal.makeSeal("火焰印");
qi.circulateQi("手少阴心经");
targetLock.lockTarget(target);
System.out.println("发射火球!🔥");
System.out.println("========================\n");
}
public void castIceball(String target) {
System.out.println("=== 如来神掌:冰球术 ===");
mantra.chantMantra("唵嘛呢叭咪吽");
handSeal.makeSeal("寒冰印");
qi.circulateQi("手太阴肺经");
targetLock.lockTarget(target);
System.out.println("发射冰球!❄️");
System.out.println("========================\n");
}
public void castThunderbolt(String target) {
System.out.println("=== 如来神掌:雷电术 ===");
mantra.chantMantra("唵嘛呢叭咪吽");
handSeal.makeSeal("雷电印");
qi.circulateQi("手厥阴心包经");
targetLock.lockTarget(target);
System.out.println("发射雷电!⚡");
System.out.println("========================\n");
}
// 终极技能
public void castRulaiPalm(String target) {
System.out.println("=== 如来神掌:终极奥义 ===");
mantra.chantMantra("唵嘛呢叭咪吽 六字真言");
handSeal.makeSeal"如来神掌印");
qi.circulateQi("任督二脉");
targetLock.lockTarget(target);
System.out.println("发射如来神掌!🙏");
System.out.println("========================\n");
}
}
第二步:使用外观
java
public class Main {
public static void main(String[] args) {
// 创建外观
MagicFacade magic = new MagicFacade();
// 简化后的调用
magic.castFireball("白骨精");
magic.castIceball("红孩儿");
magic.castThunderbolt("金角大王");
magic.castRulaiPalm("牛魔王");
}
}
输出:
=== 如来神掌:火球术 ===
念咒:唵嘛呢叭咪吽
结印:火焰印
运功:手少阴心经
锁定目标:白骨精
发射火球!🔥
========================
=== 如来神掌:冰球术 ===
念咒:唵嘛呢叭咪吽
结印:寒冰印
运功:手太阴肺经
锁定目标:红孩儿
发射冰球!❄️
========================
=== 如来神掌:雷电术 ===
念咒:唵嘛呢叭咪吽
结印:雷电印
运功:手厥阴心包经
锁定目标:金角大王
发射雷电!⚡
========================
=== 如来神掌:终极奥义 ===
念咒:唵嘛呢叭咪吽 六字真言
结印:如来神掌印
运功:任督二脉
锁定目标:牛魔王
发射如来神掌!🙏
========================
外观模式的高级用法
分层外观
java
// 初级外观:只暴露基础功能
public class BasicMagicFacade {
private MagicFacade magicFacade;
public BasicMagicFacade() {
this.magicFacade = new MagicFacade();
}
public void castFireball(String target) {
magicFacade.castFireball(target);
}
public void castIceball(String target) {
magicFacade.castIceball(target);
}
// 不暴露终极技能
}
// 高级外观:暴露全部功能
public class AdvancedMagicFacade extends MagicFacade {
public void castUltimateCombo(String target) {
// 组合技
castFireball(target);
castIceball(target);
castThunderbolt(target);
castRulaiPalm(target);
}
}
智能外观
java
// 智能外观:根据情况自动选择法术
public class SmartMagicFacade extends MagicFacade {
@Override
public void castFireball(String target) {
// 智能判断:如果目标是火免疫,改用冰球
if (isFireImmune(target)) {
System.out.println("【智能外观】目标火免疫,改用冰球!");
castIceball(target);
return;
}
super.castFireball(target);
}
private boolean isFireImmune(String target) {
return target.equals("红孩儿"); // 红孩儿火免疫
}
}
🏆 战斗总结
唐僧赞叹: "悟空,这外观模式果然精妙!为师只需一招'如来神掌',就能施法!"
悟空得意: "师父,这还不止!外观模式还能------"
| 优势 | 说明 |
|---|---|
| 简化调用 | 客户端不用关心子系统细节 |
| 松耦合 | 客户端和子系统解耦 |
| 易于使用 | 提供统一的入口 |
本章要点
| 要点 | 说明 |
|---|---|
| 核心思想 | 为子系统中的一组接口提供一个一致的界面 |
| 适用场景 | 简化复杂系统调用、分层架构、第三方库封装 |
| 优点 | 简化调用、松耦合、符合迪米特法则 |
| 缺点 | 可能违反开闭原则、过度封装 |
下回预告
话说师徒来到"天条戒律殿",取经流程已定,不可更改。如何规范?且看模板方法模式!
欲知后事如何,且听第十回分解!