
前端常用设计模式
发布日期:2021-05-07 23:09:06
浏览次数:24
分类:精选文章
本文共 5151 字,大约阅读时间需要 17 分钟。
前端设计模式是一个软件开发人员在解决复杂业务逻辑问题时常用的解决方案。它通过提前定义好软件的结构和行为模式,帮助开发者在复杂系统中保持代码的可读性和可维护性。
前端设计模式的基本准则
软件设计模式的核心在于提高代码的可维护性和复用性。以下是前端开发中常用的几种基本原则:
单一职责原则:每个类或模块只负责实现单一功能,减少代码复杂度。
开闭原则:类或模块应该对扩展开放,对修改关闭,以增强系统的灵活性和稳定性。
里式替换原则:子类可以替换父类的行为,确保系统的扩展性。
依赖倒置原则:高层模块不直接依赖低层模块,而是通过抽象层间接关联,提高系统的灵活性。
接口隔离原则:一个模块不应该暴露多余的接口,避免不必要的耦合。
迪米特原则:类之间的耦合度尽量降低,确保模块之间的独立性。
前端设计模式的种类
设计模式可以分为三大类,根据解决的问题不同,选择合适的模式:
创建型模式
用于对象的创建,常见模式包括:- 单例模式:确保一个类只有一个实例。
- 工厂方法模式:通过一个工厂类统一管理对象的创建。
- 抽象工厂模式:用于创建不同家族的产品。
- 建造者模式:逐步构建对象,提供灵活的构建方式。
- 原型模式:通过复制现有对象来创建新对象,节省内存。
结构型模式
用于处理类之间的继承关系,常见模式包括:- 适配器模式:将不兼容的接口转换为兼容的接口。
- 桥接模式:解耦两个不相关的系统。
- 组合模式:将多个对象组合在一起,形成单一的行为。
- 装饰器模式:动态地给对象增加功能。
- 外观模式:为复杂系统提供简洁的接口。
- 享元模式:通过共享单个实例来提高性能。
- 代理模式:为一个对象提供替代的行为。
- 过滤器模式:对数据进行过滤和处理。
行为型模式
用于处理算法或行为的分割,常见模式包括:- 命令模式:将操作封装成可执行的对象。
- 解释器模式:定义一个解释算法的类。
- 迭代器模式:提供一种方式来访问一个集合中的元素。
- 中介者模式:通过中介对象间接连接两个类。
- 备忘录模式:记录操作历史,支持回滚。
- 观察者模式:定义一个观察对象的行为,自动通知相关对象。
- 状态模式:通过状态切换改变对象的行为。
- 策略模式:在不同情况下选择不同的算法。
- 模板方法模式:提供一个算法的框架,子类可以选择是否实现。
- 访问者模式:将操作统一集中在访问者类中。
- 责任链模式:将责任分配给多个对象,形成链式调用。
前端设计模式的应用实例
1. 单例模式
单例模式确保一个类只有一个实例,适用于全局唯一的资源管理。
class MessageBox { show() { console.log("show"); } hide() {} static getInstance() { if (!MessageBox.instance) { MessageBox.instance = new MessageBox(); } return MessageBox.instance; }}let box3 = MessageBox.getInstance();let box4 = MessageBox.getInstance();console.log(box3 === box4); // true
2. 工厂模式
工厂模式通过一个统一的接口创建对象,减少对具体实现的依赖。
const storageMap = new Map();function createStorageModel(key, storage = localStorage) { if (storageMap.has(key)) { return storageMap.get(key); } const model = { key, set(val) { storage.setItem(this.key, JSON.stringify(val)); }, get() { let val = storage.getItem(this.key); return val && JSON.parse(val); }, remove() { storage.removeItem(this.key); }, }; storageMap.set(key, model); return model;}const themeModel = createStorageModel('local_theme', localStorage);const utmSourceModel = createStorageModel('utm_source', sessionStorage);
3. 策略模式
策略模式通过不同的算法处理不同情况,避免复杂的if...else判断。
class Schema { constructor(descriptor) { this.descriptor = descriptor; } handleRule(val, rule) { const { key, params, message } = rule; const ruleMap = { required() { return !val; }, max() { return val > params; }, validator() { return params(val); }, }; const handler = ruleMap[key]; if (handler && handler(val)) { throw message; } } validate(data) { return new Promise((resolve, reject) => { let errors = []; for (let key of Object.keys(data)) { const ruleList = this.descriptor[key]; if (!Array.isArray(ruleList) || !ruleList.length) continue; const val = data[key]; for (let rule of ruleList) { try { this.handleRule(val, rule); } catch (e) { errors.push(e.toString()); } } } if (errors.length) { reject(errors.join(',')); } else { resolve(); } }); }}const descriptor = { nickname: [ { key: "required", message: "请填写昵称" }, { key: "max", params: 6, message: "昵称最多6位字符" }, ], phone: [ { key: "required", message: "请填写电话号码" }, { key: "validator", params(val) { return !/^1\d{10}$/.test(val); }, message: "请填写正确的电话号码", }, ],};const validator = new Schema(descriptor);const params = { nickname: "", phone: "123000" };validator.validate(params).then(() => { console.log("success");}).catch((e) => { console.log(e);});
4. 状态模式
状态模式通过不同的状态切换来改变行为。
class RollingLoad { constructor() { this._currentState = 'init'; this.states = { init: { failed: 'error', complete: 'normal' }, normal: { rolling: 'loading' }, loading: { complete: 'normal', failed: 'error' }, }; this.actions = { init() { console.log('初始化加载,大loading'); }, normal() { console.log('加载成功,正常展示'); }, error() { console.log('加载失败'); }, loading() { console.log('滚动加载'); }, }; } change(state) { let to = this.states[this._currentState][state]; if (to) { this._currentState = to; this.go(); return true; } return false; } go() { this.actions[this._currentState](); return this; }}const rollingLoad = new RollingLoad();rollingLoad.go();rollingLoad.change('complete');rollingLoad.change('loading');
5. 发布-订阅模式
发布-订阅模式允许多个对象监听同一个事件,适用于异步编程。
login.addEventListener('loginSucc', function(data) { header.setAvatar(data.avatar);});login.addEventListener('loginSucc', function(data) { nav.setAvatar(data.avatar);});
6. 迭代器模式
迭代器模式提供一种方式来访问聚合对象的元素。
const platformList = [ { name: 'app', validator: isApp }, { name: 'wx', validator: isWx }, { name: 'tiktok', validator: isTiktok }, { name: 'bili', validator: isBili }, { name: 'kwai', validator: isKwai },];function getPageType() { const ua = navigator.userAgent; for (let { name, validator } of platformList) { if (validator(ua)) { return name; } }}
通过以上设计模式,前端开发者可以更高效地解决问题,提升代码的可读性和可维护性。
发表评论
最新留言
很好
[***.229.124.182]2025年03月22日 23时13分13秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
银河麒麟系统配置apt网络源
2019-03-05
Linux内核结构粗解及关于 shell 通俗理解
2019-03-05
第七周 4.12-4.18
2019-03-05
程序设计入门14 结构体
2019-03-05
程序设计基础75 tips 广度搜索细节问题
2019-03-05
笨办法学python之数据类型
2019-03-05
笨办法学Python之将对象名的字符串类型,转化成相应对象
2019-03-05
ArduPilot源码极速下载手册(一文告别github慢速问题)
2019-03-05
聊一聊那些应该了解的大佬(飞控,人工智能方向)
2019-03-05
ArduPilot+mavros+gazebo+QGC联合仿真初体验
2019-03-05
px4调试bug--添加mavlink_log_info信息
2019-03-05
redis替换字符串命令
2019-03-05
redis向数组中添加值并查看数组长度
2019-03-05
python3基础梳理11python中模块和包
2019-03-05
求出1/1-1/2+1/3-1/4…..1/100的和
2019-03-05
JS编写一个函数,计算三个不同数字的大小,按从小到大顺序打印(穷举法)
2019-03-05
js设置小球的缓冲运动
2019-03-05
jQuery实现轮播图效果
2019-03-05
restFUL
2019-03-05
mybatis中like的注意
2019-03-05