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 地址、环境变量等)。
- 配置信息应当通过
getConfig
和setConfig
方法访问和修改。 - 确保配置管理器是单例模式,即只允许有一个实例。
你可以尝试实现这个类,并在代码中模拟设置和获取配置。
在前端 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 系统中,单例模式的应用非常广泛,尤其是在需要确保全局唯一性和一致性的数据或服务中。常见的应用包括配置管理、用户认证、日志记录、数据缓存以及事件总线等。通过单例模式,你可以确保系统的性能和稳定性,避免资源浪费和冗余操作。