这是我参与「第四届青训营」笔记创作活动的第6天
本堂课重点内容:
- 设计模式背景
- 设计模式分类
- 浏览器中的设计模式
详细知识点介绍:
设计模式
代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的;设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。
设计模式背景
设计模式最早出现在建筑领域,是克里斯托弗.亚历山大(Christopher Alexander,头衔很多的大佬) 对环境中不断出现的问题, 总结出这些问题的解决方案。以后再遇到这些问题时,可以重用这些方案来解决。
什么是面向对象编程
面向对象编程是一种编程范式或编程风格。它以类或对象作为组织代码的基本单元,并将封装、抽象、继承、多态四大特性,作为代码设计和实现的基石。面向对象编程语言是支持类或对象的语法机制,并有现成的语法机制,能方便的实现面向对象编程四大特性的编程语言。面向对象开发包括面向对象分析 OOA、面向对象设计 OOD、面向对象编程 OOP。
设计模式分类(23种设计模式)
- 创建型(5种):如何创建一个对象
- 抽象工厂、工厂方法模式、单例模式、建造者模式、原型模式
- 结构型(7种):如何灵活的将对象组装成较大的结构
- 桥接模式、代理模式、装饰器模式、适配器模式、享元模式、组合模式、外观模式
- 行为型(11种):负责对象间的高效通信和职责划分
- 观察者模式、模板方法模式、迭代子模式、状态模式、命令模式、中介者模式、解释器模式、责任链模式、访问者模式、策略模式、备忘录模式
浏览器中的设计模式
- 单例模式
- 发布订阅模式
- 单例模式
- 定义:全局唯一访问变量。
- 应用场景:缓存、全局状态管理等。
如window对象
举个栗子: 用单例模式实现缓存
import { api } from "./utils";
export class Requset {
static instance: Requset;
private cache: Record<string, string>;
constructor( {
this.cache = {};
}
static getInstance() {
if (this.instance) {
return this.instance;
}
this.instance = new Requset();
return this.instance;
}
public async request(url: string) {
if (this.cache[url]) {
return this.cache[url];
}
const response = await api(url);
this.cache[url] = response;
return response;
}
}
// test.ts
test( "should response more than 500ms with class", async () => {
const request = Requset.getInstance();
const startTime = Date.now();
await request.request( "/user/1");
const endTime = Date.now();
const costTime = endTime - startTime;
expect(costTime).toBeGreaterThanOrEqual(500);
});
test( "should response quickly second time with class",async () => {
const request1 = Requset.getInstance();
await request1.request( "/user/1");
const startTime = Date.now();
const request2 = Requset.getInstance();
await request2.request("/user/1");
const endTime = Date.now();
const costTime = endTime - startTime;
expect(costTime) .toBeLessThan(50);
});
- 发布订阅模式
- 定义:一种订阅机制,可在被订阅对象发生变化时通知订阅者。
- 应用场景:从系统架构之间的解耦,到业务中一些实现模式,像邮件订阅,上线订阅等等,应用广泛。
举个栗子: 用发布订阅模式实现用户上线订阅
type Notify = (user: User) void;
export class User {
name: string;
status: "offline" | "online" ;
followers: { user: User; notify: Notify }[];
constructor(name: string) {
this.name = name;
this.status = "offline";
this.followers = [];
}
subscribe (user: User, notify: Notify) {
user.followers.push({ user, notify });
}
online() {
this.status = "online";
this.followers.forEach(({ notify }) => {
notify (this);
});
}
}
//test.ts
test("should notify followers when user is online for multiple users",() => {
const user1 = new User("user1");
const user2 = new User("user2");
const user3 = new User("user3");
const mockNotifyUser1 = jest.fn();
const mockNotifyUser2 = jest.fn();
user1.subscribe(user3, mockNotifyUser1);
user2.subscribe(user3, mockNotifyUser2);
user3.online();
expect(mockNotifyUser1).toBeCalledWith(user3);
expect(mockNotifyUser2).toBeCalledWith(user3);
});
课后个人总结:
- 总结出抽象的模式相对比较简单,但是想要将抽象的模式套用到场景中却非常困难
- 现代编程语言的多编程范式带来的更多可能性
- 真正优秀的开源项目学习设计模式并不断实践
引用参考:
《设计模式这样学也太简单了吧!》