【前端设计模式】之外观模式

外观模式是一种结构型设计模式,它提供了一个简单的接口,隐藏了复杂的子系统,并使得客户端能够更方便地使用这些子系统。在前端开发中,外观模式可以帮助我们简化复杂的代码结构,提高代码的可维护性和可读性。

外观模式特性

  1. 封装复杂的子系统:外观模式通过提供一个简单的接口,将复杂的子系统封装起来。这样客户端就不需要了解子系统内部的实现细节。
  2. 简化接口:外观模式可以将多个子系统的接口进行整合和简化,提供一个更加统一和易于使用的接口给客户端。
  3. 提高代码可维护性:通过将复杂的子系统封装起来,外观模式可以减少代码之间的依赖关系,使得代码更加易于维护和修改。

应用示例

1. 挂号系统

js 复制代码
// 创建外观对象
const HospitalFacade = {
  // 封装内部系统方法
  bookAppointment: function(patientName, date, time) {
    this.checkPatientName(patientName);
    this.checkDate(date);
    this.checkTime(time);
    this.makeAppointment(patientName, date, time);
  },

  // 检查患者姓名是否合法
  checkPatientName: function(patientName) {
    if (!patientName || patientName.length === 0) {
      throw new Error('请输入患者姓名');
    }
  },

  // 检查预约日期是否合法
  checkDate: function(date) {
    const currentDate = new Date();
    const selectedDate = new Date(date);

    if (isNaN(selectedDate.toString())) {
      throw new Error('请选择有效的预约日期');
    } else if (Math.abs(selectedDate - currentDate) < 86400000) {
      throw new Error('请选择至少在24小时后的预约日期');
    }
  },

  // 检查预约时间是否合法
  checkTime: function(time) {
    const selectedTime = new Date(time);

    if (isNaN(selectedTime.toString())) {
      throw new Error('请选择有效的预约时间');
    }
  },

  // 创建预约并保存到数据库中
  makeAppointment: function(patientName, date, time) {
    const appointment = {
      patientName: patientName,
      date: date,
      time: time,
    };
    // 调用数据库操作方法保存预约信息
    this.saveAppointmentToDatabase(appointment);
    console.log('预约成功!');
  },

  // 封装数据库操作方法,避免暴露底层细节给客户端调用
  saveAppointmentToDatabase: function(appointment) {
    // 在这里执行数据库操作,保存预约信息到数据库中...
  },
};

// 使用外观对象进行挂号操作
HospitalFacade.bookAppointment('张三', '2023-07-18', '14:00');

这段代码创建了一个名为HospitalFacade的外观对象,该对象封装了医院预约挂号系统的相关方法。

bookAppointment方法用于接受患者姓名、预约日期和时间作为参数,并依次进行以下操作:

  1. 调用checkPatientName方法检查患者姓名是否合法。
  2. 调用checkDate方法检查预约日期是否合法。
  3. 调用checkTime方法检查预约时间是否合法。
  4. 如果以上检查均通过,则调用makeAppointment方法创建预约并保存到数据库中。

这些方法对应于挂号系统的各个功能。客户端只需要与外观对象进行交互,而不需要直接与各个内部系统进行通信。这样可以简化客户端的代码,并隐藏内部系统的细节。同时,通过将一些复杂的逻辑封装在外观对象中,可以提高代码的可维护性和可读性。

2. 动画效果封装:

下面是一个示例代码,展示如何使用外观模式实现对动画效果的封装:

javascript 复制代码
// 动画效果外观类
class AnimationFacade {
  constructor() {
    this.animation = new Animation();
  }

  // 外观方法:开始动画
  startAnimation() {
    this.animation.start();
  }

  // 外观方法:停止动画
  stopAnimation() {
    this.animation.stop();
  }

  // 外观方法:更新动画帧
  updateFrame() {
    this.animation.update();
  }
}

// 动画子系统类
class Animation {
  constructor() {
    this.frames = []; // 动画帧数组
    this.currentFrameIndex = 0; // 当前帧索引
  }

  // 子系统方法:开始动画
  start() {
    // 添加开始动画帧,设置初始状态等操作
    this.frames.push(new Frame('start'));
  }

  // 子系统方法:停止动画
  stop() {
    // 添加结束动画帧,设置结束状态等操作
    this.frames.push(new Frame('stop'));
  }

  // 子系统方法:更新动画帧
  update() {
    // 根据当前帧索引和帧数组更新动画状态等操作
    const frame = this.frames[this.currentFrameIndex];
    frame.update();
  }
}

// 动画帧类
class Frame {
  constructor(type) {
    this.type = type; // 帧类型,如开始、结束等
  }

  // 更新动画帧状态等操作,具体实现根据实际需求而定
  update() {
    console.log(`Frame ${this.type} updated`);
  }
}

const animation = new AnimationFacade(); // 创建动画外观对象
animation.startAnimation(); // 开始动画
animation.updateFrame(); // 更新动画帧,输出"Frame start updated"和"Frame stop updated"等日志信息,具体输出取决于`Frame`类的实现和动画效果的具体需求。
animation.stopAnimation(); // 停止动画,输出"Frame stop updated"等日志信息。

这段代码定义了一个动画效果外观类(AnimationFacade)和两个子系统类:动画子系统类(Animation)和动画帧类(Frame)。

动画效果外观类(AnimationFacade)是整个动画系统的外观,提供了一些外观方法,用于控制动画的开始、停止和更新帧。

动画子系统类(Animation)是实现动画的核心部分,它包含了动画帧数组(frames)和当前帧索引(currentFrameIndex)。该类提供了开始动画、停止动画和更新动画帧的方法。

动画帧类(Frame)表示动画中的每一帧。它只有一个类型属性(type),用于标识帧的类型。该类还提供了一个更新方法(update),用于执行具体的动画帧更新操作。

通过使用这些类,可以构建一个简单的动画系统,通过调用外观方法来控制动画的开始、停止和更新帧。具体实现可以根据实际需求进行扩展和修改。

优缺点

优点

  1. 简化接口:外观模式可以将复杂的子系统接口进行整合和简化,提供一个更加统一和易于使用的接口给客户端。
  2. 提高代码可维护性:通过将复杂的子系统封装起来,外观模式可以减少代码之间的依赖关系,使得代码更加易于维护和修改。
  3. 提高代码可读性:外观模式可以隐藏复杂的实现细节,使得代码更加易于理解和阅读。

缺点

  1. 违反开闭原则:如果需要新增或修改子系统的功能,可能需要修改外观类的代码。
  2. 可能会造成性能问题:如果外观类过于庞大,可能会导致性能下降。

总结

外观模式是一种简化复杂系统接口的设计模式,在前端开发中有着广泛的应用。它可以帮助我们封装复杂的子系统,并提供一个简单易用的接口给客户端。通过使用外观模式,我们可以提高代码的可维护性、可读性和扩展性。但是需要注意避免过度使用外观模式,以免造成不必要的性能问题。

相关推荐
崔庆才丨静觅4 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60614 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了4 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅4 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅5 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅5 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment5 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅6 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊6 小时前
jwt介绍
前端
爱敲代码的小鱼6 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax