外观模式(Facade Pattern)
外观模式(Facade Pattern) 是一种简化跨模块交互的设计模式,它通过创建一个统一的"外观"接口,隐藏复杂子系统的内部细节,为外部提供简洁的访问入口。这在处理程序集间通信时非常有用,能有效降低模块间的耦合度。
外观模式的核心作用
- 简化复杂程序集的使用方式
- 隔离内部实现与外部访问
- 统一跨程序集的交互接口
- 减少程序集间的直接依赖
外观模式在程序集通信中的应用
假设我们有一个复杂的战斗系统程序集(CombatSystem),包含攻击、防御、技能等多个子模块,其他程序集(如UI、任务系统)需要与它交互:
1. 不使用外观模式的问题
// UI程序集直接访问战斗系统内部细节(耦合过高)
var attackSystem = CombatSystem.Instance.GetSubSystem<AttackSystem>();
var damage = attackSystem.CalculateDamage(playerWeapon, enemyDefense);
var defenseSystem = CombatSystem.Instance.GetSubSystem<DefenseSystem>();
defenseSystem.ApplyDamage(enemy, damage);
2. 使用外观模式优化
// 战斗系统程序集中定义外观类(对外暴露的唯一接口)
public class CombatFacade
{
// 隐藏的内部系统
private AttackSystem _attackSystem;
private DefenseSystem _defenseSystem;
private SkillSystem _skillSystem;
// 提供简洁的对外接口
public int CalculateDamage(Weapon weapon, Defense defense)
{
return _attackSystem.CalculateDamage(weapon, defense);
}
public void ApplyDamage(Character target, int damage)
{
_defenseSystem.ApplyDamage(target, damage);
}
public bool CastSkill(Character caster, Skill skill, Character target)
{
// 内部可能涉及多个子系统协作
if (_skillSystem.CanCast(caster, skill))
{
_skillSystem.ConsumeMana(caster, skill);
var skillDamage = _skillSystem.CalculateSkillDamage(skill, caster);
_defenseSystem.ApplyDamage(target, skillDamage);
return true;
}
return false;
}
}
3. 其他程序集的使用方式
// UI程序集只需与外观交互,无需了解内部结构
public class BattleHUD
{
private CombatFacade _combatFacade;
public void OnSkillButtonClicked(Skill selectedSkill)
{
bool success = _combatFacade.CastSkill(Player.Instance, selectedSkill, CurrentEnemy);
if (success)
{
UpdateSkillUI();
}
}
}
外观模式的优势
- 降低耦合:外部程序集只需依赖外观接口,无需了解内部实现
- 简化调用:将复杂的多步骤操作封装为单一方法
- 隔离变化:子系统内部修改时,只要外观接口不变,外部无需调整
- 明确边界:清晰定义程序集的公共功能与内部实现的界限
实现外观模式的注意事项
- 单一职责:外观类应只负责协调子系统,不添加额外业务逻辑
- 接口稳定:外观接口应保持相对稳定,避免频繁变更影响外部
- 不替代抽象:外观不是接口的替代品,复杂交互仍需定义清晰接口
- 适度设计:不要为每个程序集都创建外观,简单模块可直接暴露接口
在Unity项目中,外观模式特别适合用于以下场景:
- 复杂系统(如战斗、AI、资源管理)对外提供服务
- 第三方插件的二次封装
- 跨程序集的批量操作(如场景切换、状态重置)