一起跟AI学习JavaScript设计模式-单例模式

1. 单例模式(Singleton Pattern)

概念讲解

单例模式的目的是确保一个类只有一个实例,并提供全局访问点。换句话说,我们希望确保在整个应用中,这个类只会被实例化一次。它常用在管理资源的场景中,比如配置管理、数据库连接等。

应用场景

  • 配置管理:应用程序需要统一的配置文件,而这些配置在整个应用中是共享的。
  • 日志系统:一个日志管理器只能有一个实例来避免多个日志文件的混乱。
  • 数据库连接池:为了避免频繁创建和销毁数据库连接,保持一个共享连接池是很常见的做法。

2. 代码示例

我们通过一个简单的 Logger 来实现单例模式,保证整个应用中只有一个 Logger 实例。

javascript 复制代码
javascript
复制代码
class Logger {
  constructor() {
    if (Logger.instance) {
      return Logger.instance;  // 如果实例已存在,直接返回已存在的实例
    }
    this.logs = [];
    Logger.instance = this;  // 保存当前实例
  }

  log(message) {
    this.logs.push(message);
    console.log(message);
  }

  getLogs() {
    return this.logs;
  }
}

// 使用单例模式
const logger1 = new Logger();
const logger2 = new Logger();

logger1.log('Hello World!');
logger2.log('This is a second log message.');

// 验证两个实例是否是同一个
console.log(logger1 === logger2);  // 输出: true

// 打印日志记录
console.log(logger1.getLogs());  // 输出: ['Hello World!', 'This is a second log message.']

3. 编程题目

题目:实现一个单例模式的配置管理类(ConfigManager)。

  • 该类需要管理一些配置信息(如 API 地址、环境变量等)。
  • 配置信息应当通过 getConfigsetConfig 方法访问和修改。
  • 确保配置管理器是单例模式,即只允许有一个实例。

你可以尝试实现这个类,并在代码中模拟设置和获取配置。

在前端 ERP 项目中,单例模式是一个非常有用的设计模式,它能帮助你确保系统中某些资源或服务的唯一性。
这些资源或服务通常需要在整个应用中共享或保持一致。下面是一些典型的应用场景:

4. 配置管理

在一个大型的 ERP 项目中,系统的配置通常是全局共享的,比如 API 地址、系统主题、权限设置等。通过单例模式,可以确保配置对象只有一个实例,并且在整个应用中都能使用相同的配置。

应用场景:

  • 存储全局配置,比如 API 路径、认证 token 等。
  • 保证配置信息的更新时可以反映到所有使用该配置的地方。
arduino 复制代码
javascript
复制代码
class ConfigManager {
  constructor() {
    if (ConfigManager.instance) {
      return ConfigManager.instance;
    }
    this.config = {
      apiUrl: 'https://api.example.com',
      theme: 'dark'
    };
    ConfigManager.instance = this;
  }

  getConfig() {
    return this.config;
  }

  setConfig(config) {
    this.config = { ...this.config, ...config };
  }
}

const config1 = new ConfigManager();
const config2 = new ConfigManager();

console.log(config1 === config2);  // 输出: true

5. 用户身份验证(Authentication)

在 ERP 系统中,用户登录后的身份验证信息(如登录状态、权限信息等)通常需要在整个应用中共享。通过单例模式,可以确保只有一个身份验证服务实例,避免重复创建和管理登录状态。

应用场景:

  • 存储用户的认证信息(如 Token、用户角色、权限等)。
  • 避免在多个地方多次请求登录状态,确保一致性。
ini 复制代码
javascript
复制代码
class AuthService {
  constructor() {
    if (AuthService.instance) {
      return AuthService.instance;
    }
    this.isAuthenticated = false;
    this.userRole = '';
    AuthService.instance = this;
  }

  login(token, role) {
    this.isAuthenticated = true;
    this.userRole = role;
    console.log('Logged in:', token, role);
  }

  logout() {
    this.isAuthenticated = false;
    this.userRole = '';
    console.log('Logged out');
  }

  getStatus() {
    return { isAuthenticated: this.isAuthenticated, userRole: this.userRole };
  }
}

const auth1 = new AuthService();
const auth2 = new AuthService();

console.log(auth1 === auth2);  // 输出: true
auth1.login('abc123', 'admin');
console.log(auth2.getStatus());  // 输出: { isAuthenticated: true, userRole: 'admin' }

6. 日志管理(Logger)

在 ERP 系统中,日志记录对于调试和监控非常重要。单例模式可以确保只有一个日志实例在系统中管理所有的日志输出,避免了多实例导致的日志混乱。

应用场景:

  • 统一记录系统日志,避免重复实例化日志对象。
  • 记录操作日志、错误日志等,并集中处理。
javascript 复制代码
javascript
复制代码
class Logger {
  constructor() {
    if (Logger.instance) {
      return Logger.instance;
    }
    this.logs = [];
    Logger.instance = this;
  }

  log(message) {
    const timestamp = new Date().toISOString();
    this.logs.push(`${timestamp} - ${message}`);
    console.log(`${timestamp}: ${message}`);
  }

  getLogs() {
    return this.logs;
  }
}

const logger1 = new Logger();
const logger2 = new Logger();

logger1.log('User logged in');
logger2.log('Data fetched');

console.log(logger1 === logger2);  // 输出: true
console.log(logger1.getLogs());  // 输出: ['2024-11-22T12:00:00Z - User logged in', '2024-11-22T12:00:01Z - Data fetched']

7. 数据缓存(Cache Manager)

在大型 ERP 系统中,数据的缓存机制对性能优化至关重要。通过单例模式,可以确保整个应用中只有一个数据缓存实例,避免了重复的网络请求,减少了资源的消耗。

应用场景:

  • 缓存接口数据,减少多次请求。
  • 管理缓存的生命周期,例如过期时间、更新策略等。
kotlin 复制代码
javascript
复制代码
class CacheManager {
  constructor() {
    if (CacheManager.instance) {
      return CacheManager.instance;
    }
    this.cache = {};
    CacheManager.instance = this;
  }

  get(key) {
    return this.cache[key] || null;
  }

  set(key, value) {
    this.cache[key] = value;
  }
}

const cache1 = new CacheManager();
const cache2 = new CacheManager();

cache1.set('userProfile', { name: 'John Doe', role: 'Admin' });

console.log(cache1 === cache2);  // 输出: true
console.log(cache2.get('userProfile'));  // 输出: { name: 'John Doe', role: 'Admin' }

8. 事件总线(Event Bus)

在一个大型 ERP 系统中,组件之间通常需要进行通信。通过单例模式,可以实现一个全局的事件总线,确保不同模块之间能够通过事件进行解耦。事件总线通常用于广播消息、监听事件等。

应用场景:

  • 跨模块事件通信(如用户状态变化通知)。
  • 事件的统一管理和监听。
kotlin 复制代码
javascript
复制代码
class EventBus {
  constructor() {
    if (EventBus.instance) {
      return EventBus.instance;
    }
    this.events = {};
    EventBus.instance = this;
  }

  on(event, callback) {
    if (!this.events[event]) {
      this.events[event] = [];
    }
    this.events[event].push(callback);
  }

  emit(event, data) {
    if (this.events[event]) {
      this.events[event].forEach(callback => callback(data));
    }
  }
}

const bus1 = new EventBus();
const bus2 = new EventBus();

console.log(bus1 === bus2);  // 输出: true

bus1.on('userLogin', (data) => {
  console.log('User logged in:', data);
});

bus2.emit('userLogin', { username: 'john_doe' });  // 输出: User logged in: { username: 'john_doe' }

总结

在前端 ERP 系统中,单例模式的应用非常广泛,尤其是在需要确保全局唯一性和一致性的数据或服务中。常见的应用包括配置管理、用户认证、日志记录、数据缓存以及事件总线等。通过单例模式,你可以确保系统的性能和稳定性,避免资源浪费和冗余操作。

相关推荐
高山我梦口香糖30 分钟前
[react] <NavLink>自带激活属性
前端·javascript·react.js
撸码到无法自拔35 分钟前
React:组件、状态与事件处理的完整指南
前端·javascript·react.js·前端框架·ecmascript
高山我梦口香糖35 分钟前
[react]不能将类型“string | undefined”分配给类型“To”。 不能将类型“undefined”分配给类型“To”
前端·javascript·react.js
Elena_Lucky_baby1 小时前
实现路由懒加载的方式有哪些?
前端·javascript·vue.js
一雨方知深秋1 小时前
智慧商城:封装getters实现动态统计 + 全选反选功能
开发语言·javascript·vue2·foreach·find·every
海威的技术博客1 小时前
关于JS中的this指向问题
开发语言·javascript·ecmascript
王解2 小时前
Vue CLI 脚手架创建项目流程详解 (2)
前端·javascript·vue.js
刘大浪2 小时前
vue.js滑动到顶便锁定位置
前端·javascript·vue.js
aaasssdddd962 小时前
C++的封装(十四):《设计模式》这本书
数据结构·c++·设计模式
T1an-12 小时前
设计模式之【观察者模式】
观察者模式·设计模式