TypeScript 架构模式:如何停止编写“意大利面条式代码”并开始高效开发
\n\n你是否曾经打开一个半年前用 TypeScript 编写的项目,却惊恐地发现自己看不懂自己写的类?或者,当你添加一个新功能时,应用却在三个意想不到的地方崩溃了?听起来很熟悉?欢迎加入那些曾认为“差不多就行”并为此付出代价的开发者俱乐部。
\n\nTypeScript 不仅仅是 JavaScript 的一个带类型的超集。它是一个强大的工具,能够让你构建复杂、可扩展且易于维护的系统。但类型本身并不能拯救你于架构混乱之中。你需要架构模式——这些经过时间考验的配方,能帮助你组织代码,使其清晰、可测试且灵活。
\n\n在本文中,我们将探讨五种关键的TypeScript 架构模式,它们在实际项目中最常用。你将看到代码示例,理解每个模式的应用场景和原因,并能立即将其应用到你的工作中。我们开始吧!
\n\n1. MVC(模型-视图-控制器)——经典之作
\n\n我们从最著名的模式开始。TypeScript 中的 MVC 将应用分为三层:
\n\n- \n
- Model(模型)——数据和业务逻辑。 \n
- View(视图)——显示(用户界面)。 \n
- Controller(控制器)——连接层,处理用户输入。 \n
在TypeScript 应用中,MVC 特别出色,因为我们可以严格地为所有层定义类型,从而在编译阶段排除错误。
\n\n示例:简单的任务列表(Todo List)
\n\n// Model\ninterface Task {\n id: number;\n title: string;\n completed: boolean;\n}\n\nclass TaskModel {\n private tasks: Task[] = [];\n\n addTask(title: string): Task {\n const newTask: Task = {\n id: Date.now(),\n title,\n completed: false,\n };\n this.tasks.push(newTask);\n return newTask;\n }\n\n getTasks(): Task[] {\n return this.tasks;\n }\n}\n\n// View\nclass TaskView {\n render(tasks: Task[]): void {\n console.clear();\n tasks.forEach(task => {\n console.log(`${task.id}: [${task.completed ? 'x' : ' '}] ${task.title}`);\n });\n }\n}\n\n// Controller\nclass TaskController {\n constructor(\n private model: TaskModel,\n private view: TaskView\n ) {}\n\n addTask(title: string): void {\n this.model.addTask(title);\n this.view.render(this.model.getTasks());\n }\n\n showAll(): void {\n this.view.render(this.model.getTasks());\n }\n}\n\n// 使用\nconst model = new TaskModel();\nconst view = new TaskView();\nconst controller = new TaskController(model, view);\ncontroller.addTask('学习 TypeScript 模式');\ncontroller.addTask('写一篇文章');\n\n为什么这很酷?你可以更改 View(例如,从控制台切换到 React),而无需改动 Model。你可以独立于 UI 测试业务逻辑。TypeScript 应用的架构变得透明。
\n\n2. 观察者模式——事件之王
\n\n如果你的应用依赖于事件(点击、服务器响应、定时器),那么TypeScript 观察者模式就是你最好的朋友。它允许一个对象(订阅者)监听另一个对象(发布者)的变化。
\n\n示例:通知系统
\n\n// 观察者接口\ninterface Observer {\n update(data: string): void;\n}\n\n// 发布者\nclass NewsPublisher {\n private observers: Observer[] = [];\n\n subscribe(observer: Observer): void {\n this.observers.push(observer);\n }\n\n unsubscribe(observer: Observer): void {\n this.observers = this.observers.filter(obs => obs !== observer);\n }\n\n publishNews(news: string): void {\n this.observers.forEach(obs => obs.update(news));\n }\n}\n\n// 具体观察者:邮件通知\nclass Em