惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Vulnerabilities – Threatpost
P
Proofpoint News Feed
The Hacker News
The Hacker News
Know Your Adversary
Know Your Adversary
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Tenable Blog
AWS News Blog
AWS News Blog
S
Securelist
T
Threatpost
C
Cybersecurity and Infrastructure Security Agency CISA
IT之家
IT之家
腾讯CDC
WordPress大学
WordPress大学
Spread Privacy
Spread Privacy
C
Check Point Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Engineering at Meta
Engineering at Meta
Latest news
Latest news
A
About on SuperTechFans
The Register - Security
The Register - Security
L
LINUX DO - 热门话题
T
The Exploit Database - CXSecurity.com
C
Cisco Blogs
T
Tailwind CSS Blog
Simon Willison's Weblog
Simon Willison's Weblog
阮一峰的网络日志
阮一峰的网络日志
MyScale Blog
MyScale Blog
大猫的无限游戏
大猫的无限游戏
T
Tor Project blog
L
Lohrmann on Cybersecurity
G
GRAHAM CLULEY
B
Blog RSS Feed
Scott Helme
Scott Helme
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
NISL@THU
NISL@THU
P
Privacy International News Feed
Security Latest
Security Latest
Recorded Future
Recorded Future
L
LangChain Blog
Cyberwarzone
Cyberwarzone
C
Cyber Attacks, Cyber Crime and Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 聂微东
Google DeepMind News
Google DeepMind News
Last Week in AI
Last Week in AI
Apple Machine Learning Research
Apple Machine Learning Research
F
Fortinet All Blogs
O
OpenAI News
T
Threat Research - Cisco Blogs
Blog — PlanetScale
Blog — PlanetScale

掘金

Win 安装Claude Code FastAPI 的 CORSMiddleware 跨域中间件 Java 自研 ReAct Agent 半年后,我用 LangGraph 验证了这些设计取舍 🚀AI编程工作流终极形态:GitNexus!零Token消耗实现代码知识图谱化!让Claude Code和Codex拥有上帝视角彻底告别盲目改代码,复杂项目重 LeetCode 72. 编辑距离:动态规划经典题解 被The Graph的GraphQL查询坑了三天,我用一个真实DeFi项目把链上数据索引彻底搞懂了 (AI) 编写简单 AI 助手 (ds-agent) 别再让 pnpm 跟着 nvm 跑了!独立安装终极指南 Claude Code 为什么这么顺?Anthropic 最新复盘:真正撑住它的不是模型,而是缓存 从 /simplify 指令深挖 Claude Code 多 Agent 协同机制 Function-Calling与工具使用 新手上路(六):Claude code装上ECC全家桶:38 个子代理、156 个技能、生产级 Hooks 与 Rules 体系 我在 Claude、Kimi、opencode 三个 AI 之间搭了一条自动协作管道 【技能篇】OpenClaw Skill 详解:给 AI 装上"专业外挂" wagmi v2 多链钱包切换:一个 Uniswap 仿盘项目让我踩了三天坑 两周浅学 RAG 我把 Python re 模块比喻成摸金手套 新手上路(三):Claude Code Skills 装了一堆没用?20+ 个 Skill 横向对比 + 三套组合方案,按需抄 K2.6、DeepSeek V4、GPT-5.5 都来了,组合拳打起来 Claude Code 进阶之路:从记忆系统到子代理编排 [java] 编译之后的记录类(Record Classes)长什么样子(上) 国产大模型能力大比拼,社区有话说 我研读了 500 个 Spring Boot 生产级代码库,90% 都犯了这 7 个致命错误 JAVA重点难点 转发-中央网信办部署开展“清朗·整治AI应用乱象”专项行动 合同同步逻辑 【合并已排序数组的三种实现策略,哪一种更可取?】 30天减20斤挑战:少一斤发100红包(2) 我竟然被JavaScript的隐式类型转换坑了三天! 二十五.Electron 初体验与进阶 本地到生产,解决 AI 全栈最后一公里——构建&部署&运维 程序员创业半年:顺的事、不顺的事,和我一直没想清楚的事 UI组件库elementplus 像使用 Redis 一样操作 LocalStorage 向量检索的流程是怎样的?Embedding 和 Rerank 各自的作用? LangChain DeepAgents 速通指南(七)—— DeepAgents使用Agent Skill 为什么越来越多的大厂抛弃MCP,转向CLI? 【节点】[SquareRoot节点]原理解析与实际应用 「AI学习笔记」RNN从 RNN 简单介绍 在 Transformer 出现之前,序列建模领域的主角长期是 RNN 及其 juejin.cn 从 “存得下” 到 “算得快”:工业物联网需要新一代时序数据平台越来越多工业用户开始意识到一个问题:**数据是存下来了, - 掘金 放弃 Claude 订阅?我用 8 年前的服务器,强跑 Google 最强开源模型 Gemma 4 真实测评! Python开发者狂喜!200+课时FastAPI全栈实战合集,10大模块持续更新中🔥 从 Claw-Code 看 AI 驱动的大型项目开发:2 人 + 10 个自治 Agent 如何产出 48K 行 Rust 代码 秒级创建实例,火山引擎 Milvus Serverless 让 AI Agent 开发更快更省火山引擎MilvusSer MediaPlayer 播放器架构:NuPlayer 的 Source/Decoder/Renderer 三驾马车 juejin.cn 【OpenClaw】通过 Nanobot 源码学习架构---(7)Memory【OpenClaw】通过 Nanobot - 掘金 ArkClaw:以 SLI 度量驱动,构建新一代 Agent 全链路可观测体系针对AI Agent系统黑盒化问题,提出了 juejin.cn juejin.cn juejin.cn OrbStack:一键将你的 Mac 变为本地服务器 NginxPulse:Nginx日志监控革命!实时洞察Web流量与安全态势的智能利器引言:当Nginx日志成为运维的“数 - 掘金 juejin.cn 大V说’AI替代不了你’,但现实是——用AI的人正在替代你2026年是AI落地的元年,自从Claude Code爆火之后 - 掘金 一套能落地的"防 Bug"习惯:不用加班也能少出错 你以为是技术问题,其实是流程问题:工程效率的真相引言 在软件工程领域,效率问题始终是团队管理者和工程师们关注的焦点。当项 - 掘金 大模型工程三驾马车:Prompt Engineering、Context Engineering 与 Harness Engineering 深度解析 SpringBoot里的这个坑差点让我加班到天亮SpringBoot里的这个坑差点让我加班到天亮** -- 引言 Spr - 掘金 4.响应式系统基础:从发布订阅模式的角度理解 Vue3 的数据响应式原理本文从发布订阅模式的核心思想出发,深入剖析了 V - 掘金 慌了!Android 17 取消图标文字,你的 App 可能要找不到了用户终于可以隐藏桌面图标下面的文字了。 这个功能在 栗子前端技术周刊第 124 期 - ESLint v10.2.0、React Native 0.85、Node.js 25.9.0... 我用 AI 搓了一个"比谁更持久"的微信小游戏,AI实现只用了一天,微信审核却用了一个月!!!起因:一个沙雕想法的诞生 - 掘金 juejin.cn 第12章 工具(Tools)与函数调用(LangChain实战)在前几章中,我们搭建的RAG系统、对话链,核心能力局限 - 掘金 juejin.cn CmComposeUI —— 基于 Kotlin Multiplatform Compose 的 UI 组件库 Android 开发的 AI coding 与 AI debugging在目前整个行业都在大规模使用 AI coding 第四章:我是如何扒开 Claude Code 记忆与上下文压缩机制的大家好。今天,我们将来到 Claude Code 源 【从0到1构建一个ClaudeAgent】规划与协调-技能 这里解决了 Agent 开发中的一个核心痛点:**上下文窗口 - 掘金 Laravel13 + Vue3 的免费可商用 PHP 管理后台 CatchAdmin V5.2.0 发布Laravel juejin.cn 一文搞懂Harness Engineering与Meta-Harness 越用越强不是广告语:拆解 Hermes Agent 的三层学习机制 P2G-Python字符串方法完全指南-split、join、strip、replace的Python编程利器 AI 周刊【2026.04.06-04.12】:Anthropic 藏起最强模型、AI 社会矛盾激化、"欢乐马"登顶 从 AI Skills 学实战技能(六):让 AI 帮你总结网页、PDF、视频 关于10年工作经验的程序员对OpenClaw的实战经验分享以及看法 详解 karpathy 的 microgpt:实现一个浏览器运行的 gpt 不用 Tailscale:3 步把 Mac mini 通过 FRP 暴露到公网(稳定开机自启) P2B-Python可迭代对象完全指南-从列表到生成器的Python编程利器 手把手带你部署本地模型,让你Token自由(小白专属) juejin.cn 10分钟掌握 JSON-RPC 协议,面试加分、设计不踩坑 ReAct:让大模型学会边想边做 聊聊AI的发展史,AI的爆发并不是偶然 Python的列表推导式里藏了个坑,差点让我加班到凌晨 重排、重绘与合成——浏览器渲染性能的底层逻辑 podman与docker的区别和生产环境最佳实践 juejin.cn ConcurrentHashMap线程安全实现原理全解析 juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn OpenAI Codex深度解析:终端里的AI代码特工,一个指令重构整个项目 UE5.6 Cesium 插件编译踩坑记录(UE 5.6 + MSVC 14.38 + CMake 3.31)
JS 技巧:设计模式(上)
Csvn · 2026-05-17 · via 掘金

引言

设计模式是软件工程中经过验证的解决方案模板,能帮助开发者写出更优雅、可维护的代码。在前端开发中,合理运用设计模式可以显著提升代码质量。今天我们来深入探讨三种最常用的设计模式:单例模式工厂模式观察者模式

一、单例模式(Singleton Pattern)

核心概念

单例模式确保一个类只有一个实例,并提供全局访问点。这在需要共享资源的场景中非常有用,比如数据库连接、配置管理、状态存储等。

实现方式

1. 基础实现

class Singleton {
  constructor() {
    if (Singleton.instance) {
      return Singleton.instance;
    }
    Singleton.instance = this;
  }
  
  getData() {
    return this.data;
  }
  
  setData(value) {
    this.data = value;
  }
}

// 使用
const instance1 = new Singleton();
const instance2 = new Singleton();

console.log(instance1 === instance2); // true

2. 惰性初始化(推荐)

class LazySingleton {
  static instance = null;
  
  static getInstance() {
    if (!LazySingleton.instance) {
      LazySingleton.instance = new LazySingleton();
    }
    return LazySingleton.instance;
  }
  
  constructor() {
    // 私有化构造函数
    if (LazySingleton.instance) {
      throw new Error('Use getInstance() instead');
    }
  }
}

// 使用
const singleton1 = LazySingleton.getInstance();
const singleton2 = LazySingleton.getInstance();

console.log(singleton1 === singleton2); // true

3. 实际应用:全局状态管理

class Store {
  static instance = null;
  
  static getInstance() {
    if (!Store.instance) {
      Store.instance = new Store();
    }
    return Store.instance;
  }
  
  constructor() {
    this.state = {};
    this.listeners = [];
  }
  
  setState(key, value) {
    this.state[key] = value;
    this.notify();
  }
  
  getState(key) {
    return this.state[key];
  }
  
  subscribe(callback) {
    this.listeners.push(callback);
  }
  
  notify() {
    this.listeners.forEach(cb => cb(this.state));
  }
}

// 使用
const store1 = Store.getInstance();
const store2 = Store.getInstance();

store1.setState('user', { name: '张三' });
console.log(store2.getState('user')); // { name: '张三' }

二、工厂模式(Factory Pattern)

核心概念

工厂模式用于创建对象,而无需指定具体的类。它提供了一种将对象创建逻辑封装起来的方式,提高代码的灵活性和可扩展性。

实现方式

1. 简单工厂

class User {
  constructor(name, email) {
    this.name = name;
    this.email = email;
  }
  
  greet() {
    return `Hello, I'm ${this.name}`;
  }
}

class Admin {
  constructor(name, email, role) {
    this.name = name;
    this.email = email;
    this.role = role;
  }
  
  greet() {
    return `Hello, I'm ${this.name}, admin`;
  }
  
  canManage() {
    return true;
  }
}

// 工厂函数
function createUser(type, name, email, role) {
  if (type === 'user') {
    return new User(name, email);
  } else if (type === 'admin') {
    return new Admin(name, email, role);
  }
  throw new Error('Invalid user type');
}

// 使用
const user = createUser('user', '张三', 'zhang@example.com');
const admin = createUser('admin', '李四', 'li@example.com', 'super');

console.log(user.greet()); // Hello, I'm 张三
console.log(admin.canManage()); // true

2. 工厂类

class ComponentFactory {
  static create(type, config) {
    switch (type) {
      case 'button':
        return new ButtonComponent(config);
      case 'input':
        return new InputComponent(config);
      case 'modal':
        return new ModalComponent(config);
      default:
        throw new Error(`Unknown component type: ${type}`);
    }
  }
}

class ButtonComponent {
  constructor({ label, onClick }) {
    this.label = label;
    this.onClick = onClick;
  }
  
  render() {
    return `<button onclick="${this.onClick}">${this.label}</button>`;
  }
}

class InputComponent {
  constructor({ placeholder, type = 'text' }) {
    this.placeholder = placeholder;
    this.type = type;
  }
  
  render() {
    return `<input type="${this.type}" placeholder="${this.placeholder}">`;
  }
}

class ModalComponent {
  constructor({ title, content }) {
    this.title = title;
    this.content = content;
  }
  
  render() {
    return `
      <div class="modal">
        <h2>${this.title}</h2>
        <p>${this.content}</p>
      </div>
    `;
  }
}

// 使用
const button = ComponentFactory.create('button', { 
  label: '点击', 
  onClick: 'alert("clicked")' 
});
const input = ComponentFactory.create('input', { 
  placeholder: '请输入...' 
});

console.log(button.render());
console.log(input.render());

3. 实际应用:API 请求工厂

class APIFactory {
  static create(type) {
    const baseURL = 'https://api.example.com';
    
    switch (type) {
      case 'users':
        return new UsersAPI(baseURL);
      case 'posts':
        return new PostsAPI(baseURL);
      case 'comments':
        return new CommentsAPI(baseURL);
      default:
        throw new Error('Unknown API type');
    }
  }
}

class BaseAPI {
  constructor(baseURL) {
    this.baseURL = baseURL;
  }
  
  async request(endpoint, options = {}) {
    const response = await fetch(`${this.baseURL}${endpoint}`, {
      ...options,
      headers: {
        'Content-Type': 'application/json',
        ...options.headers
      }
    });
    return response.json();
  }
}

class UsersAPI extends BaseAPI {
  async getAll() {
    return this.request('/users');
  }
  
  async getById(id) {
    return this.request(`/users/${id}`);
  }
  
  async create(data) {
    return this.request('/users', {
      method: 'POST',
      body: JSON.stringify(data)
    });
  }
}

class PostsAPI extends BaseAPI {
  async getAll() {
    return this.request('/posts');
  }
  
  async getByUser(userId) {
    return this.request(`/posts?userId=${userId}`);
  }
}

// 使用
const usersAPI = APIFactory.create('users');
const postsAPI = APIFactory.create('posts');

// 获取所有用户
usersAPI.getAll().then(users => console.log(users));

// 获取某用户的所有文章
postsAPI.getByUser(1).then(posts => console.log(posts));

三、观察者模式(Observer Pattern)

核心概念

观察者模式定义了一种一对多的依赖关系,当一个对象(被观察者)状态改变时,所有依赖它的对象(观察者)都会收到通知。这是前端事件系统和状态管理的核心模式。

实现方式

1. 基础实现

class Subject {
  constructor() {
    this.observers = [];
  }
  
  attach(observer) {
    this.observers.push(observer);
  }
  
  detach(observer) {
    this.observers = this.observers.filter(obs => obs !== observer);
  }
  
  notify(data) {
    this.observers.forEach(observer => observer.update(data));
  }
}

class Observer {
  constructor(name) {
    this.name = name;
  }
  
  update(data) {
    console.log(`${this.name} received:`, data);
  }
}

// 使用
const subject = new Subject();
const observer1 = new Observer('观察者 1');
const observer2 = new Observer('观察者 2');

subject.attach(observer1);
subject.attach(observer2);

subject.notify('Hello, observers!');

// 输出:
// 观察者 1 received: Hello, observers!
// 观察者 2 received: Hello, observers!

2. 实际应用:事件总线

class EventBus {
  constructor() {
    this.events = {};
  }
  
  on(event, callback) {
    if (!this.events[event]) {
      this.events[event] = [];
    }
    this.events[event].push(callback);
  }
  
  off(event, callback) {
    if (!this.events[event]) return;
    
    if (callback) {
      this.events[event] = this.events[event].filter(cb => cb !== callback);
    } else {
      this.events[event] = [];
    }
  }
  
  emit(event, data) {
    if (!this.events[event]) return;
    
    this.events[event].forEach(callback => callback(data));
  }
  
  once(event, callback) {
    const wrapper = (data) => {
      callback(data);
      this.off(event, wrapper);
    };
    this.on(event, wrapper);
  }
}

// 使用
const eventBus = new EventBus();

// 订阅事件
eventBus.on('user:login', (user) => {
  console.log('用户登录:', user);
});

eventBus.on('user:login', (user) => {
  console.log('记录登录日志:', user);
});

// 触发事件
eventBus.emit('user:login', { id: 1, name: '张三' });

// 输出:
// 用户登录:{ id: 1, name: '张三' }
// 记录登录日志:{ id: 1, name: '张三' }

3. 实际应用:Vue 3 响应式系统

class ReactiveSystem {
  constructor() {
    this.targetStack = [];
  }
  
  track(target, key) {
    if (this.targetStack.length === 0) return;
    
    const activeEffect = this.targetStack[this.targetStack.length - 1];
    
    if (!this.reactiveMap) {
      this.reactiveMap = new WeakMap();
    }
    
    if (!this.reactiveMap.has(target)) {
      this.reactiveMap.set(target, new Map());
    }
    
    const depsMap = this.reactiveMap.get(target);
    
    if (!depsMap.has(key)) {
      depsMap.set(key, new Set());
    }
    
    depsMap.get(key).add(activeEffect);
  }
  
  trigger(target, key) {
    if (!this.reactiveMap) return;
    
    const depsMap = this.reactiveMap.get(target);
    if (!depsMap) return;
    
    const deps = depsMap.get(key);
    if (!deps) return;
    
    deps.forEach(effect => effect());
  }
  
  effect(fn) {
    const effectFn = () => {
      this.targetStack.push(effectFn);
      fn();
      this.targetStack.pop();
    };
    effectFn();
    return effectFn;
  }
}

// 使用
const system = new ReactiveSystem();

const state = { count: 0 };

system.effect(() => {
  system.track(state, 'count');
  console.log('当前计数:', state.count);
});

// 更新状态
state.count = 1;
system.trigger(state, 'count');

// 输出:
// 当前计数:0
// 当前计数:1

总结

今天我们一起学习了三种重要的设计模式:

  1. 单例模式:确保唯一实例,适用于全局状态管理、配置中心等场景
  2. 工厂模式:封装对象创建逻辑,提高代码灵活性和可扩展性
  3. 观察者模式:实现对象间的一对多依赖,是事件系统和响应式编程的基础

这些模式在前端开发中无处不在,理解它们能帮助你写出更优雅、可维护的代码。下篇我们将继续探讨策略模式装饰器模式代理模式