JavaScript设计模式与架构实战:构建可维护的企业级应用指南

探索如何运用现代JavaScript设计模式和架构原则构建健壮、可扩展的前端应用

JavaScript设计模式概述

设计模式是解决常见软件设计问题的可重用方案。在JavaScript中,设计模式的应用可以帮助我们创建更加模块化、可维护和可扩展的代码结构。

为什么需要设计模式?

  • 提高代码的可读性和可维护性
  • 促进团队协作和代码复用
  • 降低系统各部分之间的耦合度
  • 提供经过验证的解决方案

创建型设计模式

工厂模式 (Factory Pattern)

工厂模式提供了一种创建对象的接口,而不需要指定具体的类。

// 用户工厂示例
class UserFactory {
    static createUser(type, userData) {
        switch (type) {
            case 'admin':
                return new AdminUser(userData);
            case 'customer':
                return new CustomerUser(userData);
            case 'moderator':
                return new ModeratorUser(userData);
            default:
                throw new Error('未知的用户类型');
        }
    }
}

class AdminUser {
    constructor(data) {
        this.role = 'admin';
        this.permissions = ['create', 'read', 'update', 'delete', 'manage_users'];
        Object.assign(this, data);
    }
}

class CustomerUser {
    constructor(data) {
        this.role = 'customer';
        this.permissions = ['read', 'purchase'];
        Object.assign(this, data);
    }
}

// 使用工厂
const admin = UserFactory.createUser('admin', {
    name: '张三',
    email: 'zhang@example.com'
});

console.log(admin); // AdminUser实例
                

单例模式 (Singleton Pattern)

确保一个类只有一个实例,并提供全局访问点。

// 应用配置单例
class AppConfig {
    constructor() {
        if (AppConfig.instance) {
            return AppConfig.instance;
        }
        
        this.settings = {
            apiUrl: 'https://api.example.com',
            theme: 'dark',
            language: 'zh-CN',
            maxConnections: 10
        };
        
        AppConfig.instance = this;
        return this;
    }

    static getInstance() {
        if (!AppConfig.instance) {
            AppConfig.instance = new AppConfig();
        }
        return AppConfig.instance;
    }

    getSetting(key) {
        return this.settings[key];
    }

    setSetting(key, value) {
        this.settings[key] = value;
        this.saveToStorage();
    }

    saveToStorage() {
        localStorage.setItem('appConfig', JSON.stringify(this.settings));
    }

    loadFromStorage() {
        const saved = localStorage.getItem('appConfig');
        if (saved) {
            this.settings = { ...this.settings, ...JSON.parse(saved) };
        }
    }
}

// 使用单例
const config1 = new AppConfig();
const config2 = new AppConfig();

console.log(config1 === config2); // true

config1.setSetting('theme', 'light');
console.log(config2.getSetting('theme')); // 'light'
                

结构型设计模式

装饰器模式 (Decorator Pattern)

动态地给对象添加额外的职责,而不改变其结构。

// 基础日志器类
class Logger {
    log(message) {
        console.log(`基础日志: ${message}`);
    }
}

// 装饰器基类
class LoggerDecorator {
    constructor(logger) {
        this.logger = logger;
    }

    log(message) {
        this.logger.log(message);
    }
}

// 时间戳装饰器
class TimestampDecorator extends LoggerDecorator {
    log(message) {
        const timestamp = new Date().toISOString();
        super.log(`[${timestamp}] ${message}`);
    }
}

// 级别装饰器
class LevelDecorator extends LoggerDecorator {
    constructor(logger, level = 'INFO') {
        super(logger);
        this.level = level;
    }

    log(message) {
        super.log(`[${this.level}] ${message}`);
    }
}

// 使用装饰器
let logger = new Logger();
logger = new TimestampDecorator(logger);
logger = new LevelDecorator(logger, 'DEBUG');

logger.log('用户登录成功');
// 输出: [DEBUG] [2023-11-10T10:30:00.000Z] 用户登录成功
                

适配器模式 (Adapter Pattern)

使接口不兼容的对象能够相互合作。

// 第三方支付服务(不兼容的接口)
class ThirdPartyPayment {
    makePayment(amount, currency, recipient) {
        console.log(`支付 ${amount} ${currency} 给 ${recipient}`);
        return Math.random().toString(36).substr(2, 9); // 模拟交易ID
    }
}

// 我们的支付接口
class PaymentService {
    pay(amount, options = {}) {
        throw new Error('必须实现pay方法');
    }
}

// 适配器
class PaymentAdapter extends PaymentService {
    constructor(thirdPartyPayment) {
        super();
        this.thirdPartyPayment = thirdPartyPayment;
    }

    pay(amount, options = {}) {
        const {
            currency = 'USD',
            recipient = 'default-recipient',
            description = ''
        } = options;

        const transactionId = this.thirdPartyPayment.makePayment(
            amount, currency, recipient
        );

        return {
            success: true,
            transactionId,
            amount,
            currency,
            timestamp: new Date(),
            description
        };
    }
}

// 使用适配器
const thirdPartyPayment = new ThirdPartyPayment();
const paymentService = new PaymentAdapter(thirdPartyPayment);

const result = paymentService.pay(100, {
    currency: 'CNY',
    recipient: '商家A',
    description: '购买商品'
});

console.log(result);
                

行为型设计模式

观察者模式 (Observer Pattern)

定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖者都会收到通知。

// 主题(被观察者)
class Subject {
    constructor() {
        this.observers = [];
        this.state = null;
    }

    addObserver(observer) {
        this.observers.push(observer);
    }

    removeObserver(observer) {
        this.observers = this.observers.filter(obs => obs !== observer);
    }

    notifyObservers() {
        this.observers.forEach(observer => {
            observer.update(this.state);
        });
    }

    setState(state) {
        this.state = state;
        this.notifyObservers();
    }
}

// 观察者接口
class Observer {
    update(state) {
        throw new Error('必须实现update方法');
    }
}

// 具体观察者
class LoggerObserver extends Observer {
    update(state) {
        console.log(`状态更新: ${JSON.stringify(state)}`);
    }
}

class StorageObserver extends Observer {
    update(state) {
        localStorage.setItem('appState', JSON.stringify(state));
    }
}

class UIObserver extends Observer {
    constructor(elementId) {
        super();
        this.element = document.getElementById(elementId);
    }

    update(state) {
        if (this.element) {
            this.element.textContent = JSON.stringify(state, null, 2);
        }
    }
}

// 使用观察者模式
const subject = new Subject();

subject.addObserver(new LoggerObserver());
subject.addObserver(new StorageObserver());
subject.addObserver(new UIObserver('state-display'));

// 状态改变会自动通知所有观察者
subject.setState({ user: '张三', isLoggedIn: true });
subject.setState({ user: '张三', isLoggedIn: true, theme: 'dark' });
                

策略模式 (Strategy Pattern)

定义一系列算法,将它们封装起来,并且使它们可以相互替换。

// 策略接口
class ValidationStrategy {
    validate(value) {
        throw new Error('必须实现validate方法');
    }
}

// 具体策略
class EmailValidation extends ValidationStrategy {
    validate(value) {
        const emailRegex = /^[^s@]+@[^s@]+.[^s@]+$/;
        return emailRegex.test(value);
    }
}

class PhoneValidation extends ValidationStrategy {
    validate(value) {
        const phoneRegex = /^1[3-9]d{9}$/;
        return phoneRegex.test(value);
    }
}

class RequiredValidation extends ValidationStrategy {
    validate(value) {
        return value !== undefined && value !== null && value !== '';
    }
}

class MinLengthValidation extends ValidationStrategy {
    constructor(minLength) {
        super();
        this.minLength = minLength;
    }

    validate(value) {
        return value && value.length >= this.minLength;
    }
}

// 验证上下文
class Validator {
    constructor() {
        this.strategies = [];
    }

    addStrategy(strategy) {
        this.strategies.push(strategy);
    }

    validate(value) {
        const errors = [];
        
        this.strategies.forEach((strategy, index) => {
            if (!strategy.validate(value)) {
                errors.push(`验证策略 ${index + 1} 失败`);
            }
        });

        return {
            isValid: errors.length === 0,
            errors
        };
    }
}

// 使用策略模式
const emailValidator = new Validator();
emailValidator.addStrategy(new RequiredValidation());
emailValidator.addStrategy(new EmailValidation());

const passwordValidator = new Validator();
passwordValidator.addStrategy(new RequiredValidation());
passwordValidator.addStrategy(new MinLengthValidation(6));

// 测试验证
console.log(emailValidator.validate('test@example.com'));
console.log(emailValidator.validate('invalid-email'));

console.log(passwordValidator.validate('short'));
console.log(passwordValidator.validate('longenough'));
                

前端应用架构模式

MVVM架构 (Model-View-ViewModel)

MVVM模式将用户界面与业务逻辑分离,通过数据绑定实现自动同步。

// 简单的MVVM实现
class Observable {
    constructor() {
        this._value = null;
        this._listeners = [];
    }

    get value() {
        return this._value;
    }

    set value(newValue) {
        if (this._value !== newValue) {
            this._value = newValue;
            this._notifyListeners();
        }
    }

    subscribe(listener) {
        this._listeners.push(listener);
    }

    _notifyListeners() {
        this._listeners.forEach(listener => listener(this._value));
    }
}

// ViewModel
class UserViewModel {
    constructor() {
        this.name = new Observable();
        this.email = new Observable();
        this.isValid = new Observable();
        
        // 自动验证
        this.name.subscribe(() => this._validate());
        this.email.subscribe(() => this._validate());
    }

    _validate() {
        const nameValid = this.name.value && this.name.value.length >= 2;
        const emailValid = this.email.value && this.email.value.includes('@');
        this.isValid.value = nameValid && emailValid;
    }

    toModel() {
        return {
            name: this.name.value,
            email: this.email.value
        };
    }
}

// 视图绑定
function bindInputToObservable(inputElement, observable) {
    inputElement.value = observable.value || '';
    
    inputElement.addEventListener('input', (e) => {
        observable.value = e.target.value;
    });
    
    observable.subscribe(value => {
        if (inputElement.value !== value) {
            inputElement.value = value || '';
        }
    });
}

// 使用MVVM
const viewModel = new UserViewModel();

// 绑定UI元素
bindInputToObservable(document.getElementById('name-input'), viewModel.name);
bindInputToObservable(document.getElementById('email-input'), viewModel.email);

// 监听验证状态
viewModel.isValid.subscribe(isValid => {
    document.getElementById('submit-btn').disabled = !isValid;
});
                

实战案例:电商购物车系统

需求分析

构建一个完整的电商购物车系统,包含以下功能:

  • 商品添加、删除、数量修改
  • 价格计算(包括折扣、税费、运费)
  • 库存验证
  • 持久化存储
  • 优惠券应用

实现代码

// 购物车项
class CartItem {
    constructor(product, quantity = 1) {
        this.product = product;
        this.quantity = quantity;
    }

    get totalPrice() {
        return this.product.price * this.quantity;
    }

    increaseQuantity(amount = 1) {
        this.quantity += amount;
    }

    decreaseQuantity(amount = 1) {
        this.quantity = Math.max(0, this.quantity - amount);
    }
}

// 购物车
class ShoppingCart {
    constructor() {
        this.items = new Map();
        this.coupons = new Set();
        this.taxRate = 0.08; // 8%税率
        this.shippingCost = 5.99;
    }

    addItem(product, quantity = 1) {
        if (this.items.has(product.id)) {
            this.items.get(product.id).increaseQuantity(quantity);
        } else {
            this.items.set(product.id, new CartItem(product, quantity));
        }
        this._saveToStorage();
    }

    removeItem(productId) {
        this.items.delete(productId);
        this._saveToStorage();
    }

    updateQuantity(productId, quantity) {
        const item = this.items.get(productId);
        if (item) {
            if (quantity <= 0) {
                this.removeItem(productId);
            } else {
                item.quantity = quantity;
                this._saveToStorage();
            }
        }
    }

    applyCoupon(code) {
        this.coupons.add(code);
        this._saveToStorage();
    }

    removeCoupon(code) {
        this.coupons.delete(code);
        this._saveToStorage();
    }

    get subtotal() {
        let total = 0;
        for (const item of this.items.values()) {
            total += item.totalPrice;
        }
        return total;
    }

    get discount() {
        // 简单的折扣计算逻辑
        let discount = 0;
        if (this.coupons.has('SAVE10')) {
            discount += this.subtotal * 0.1;
        }
        if (this.coupons.has('FREESHIPPING')) {
            discount += this.shippingCost;
        }
        return discount;
    }

    get tax() {
        return (this.subtotal - this.discount) * this.taxRate;
    }

    get total() {
        return this.subtotal - this.discount + this.tax + this.shippingCost;
    }

    get itemCount() {
        let count = 0;
        for (const item of this.items.values()) {
            count += item.quantity;
        }
        return count;
    }

    clear() {
        this.items.clear();
        this.coupons.clear();
        this._saveToStorage();
    }

    _saveToStorage() {
        const cartData = {
            items: Array.from(this.items.entries()),
            coupons: Array.from(this.coupons),
            timestamp: new Date().toISOString()
        };
        localStorage.setItem('shoppingCart', JSON.stringify(cartData));
    }

    loadFromStorage() {
        const saved = localStorage.getItem('shoppingCart');
        if (saved) {
            const cartData = JSON.parse(saved);
            this.items = new Map(cartData.items);
            this.coupons = new Set(cartData.coupons);
        }
    }

    // 迭代器支持
    [Symbol.iterator]() {
        return this.items.values();
    }
}

// 商品类
class Product {
    constructor(id, name, price, stock = 0) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.stock = stock;
    }
}

// 使用示例
const cart = new ShoppingCart();

// 添加商品
const product1 = new Product(1, 'JavaScript高级编程', 89.99, 10);
const product2 = new Product(2, 'CSS权威指南', 79.99, 5);

cart.addItem(product1, 2);
cart.addItem(product2, 1);

// 应用优惠券
cart.applyCoupon('SAVE10');

console.log('商品数量:', cart.itemCount);
console.log('小计:', cart.subtotal.toFixed(2));
console.log('折扣:', cart.discount.toFixed(2));
console.log('税费:', cart.tax.toFixed(2));
console.log('总计:', cart.total.toFixed(2));

// 支持迭代
for (const item of cart) {
    console.log(`${item.product.name} x ${item.quantity}`);
}
                

JavaScript设计模式与架构实战:构建可维护的企业级应用指南
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

淘吗网 javascript JavaScript设计模式与架构实战:构建可维护的企业级应用指南 https://www.taomawang.com/web/javascript/1027.html

下一篇:

已经没有下一篇了!

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务