前端设计模式

前端设计模式

模板方法模式

  • 是什么
    • 定义算法骨架的设计模式,允许子类在不改变算法结构的情况下重新定义算法的某些步骤。
  • 怎么使用
    • 创建一个基类,定义一个模板方法,该方法调用由子类实现的抽象方法。
  • 应用场景
    • 当你有一个算法,但具体步骤因子类不同而不同时。
  • 例子
    • 在前端开发中,一个基础的表单验证流程可以使用模板方法模式。
  class FormValidator {
      validate() {
          this.validateRequiredFields();
          this.validateEmailFormat();
          this.validatePasswordStrength();
      }
      
      validateRequiredFields() {
          throw new Error('This method should be overridden');
      }
      
      validateEmailFormat() {
          throw new Error('This method should be overridden');
      }
      
      validatePasswordStrength() {
          throw new Error('This method should be overridden');
      }
  }

  class CustomFormValidator extends FormValidator {
      validateRequiredFields() {
          console.log('Validating required fields');
      }
      
      validateEmailFormat() {
          console.log('Validating email format');
      }
      
      validatePasswordStrength() {
          console.log('Validating password strength');
      }
  }

  const validator = new CustomFormValidator();
  validator.validate();

单例模式

  • 是什么
    • 确保一个类只有一个实例,并提供一个全局访问点。
  • 怎么使用
    • 使用闭包和立即执行函数表达式(IIFE)来实现。
  • 应用场景
    • 当需要确保某个类的唯一实例,如全局的应用状态管理器。
  • 例子
    • Redux 的 store 对象就是一个单例模式的例子。
const Singleton = (function() {
    let instance;

    function createInstance() {
        const object = new Object('I am the instance');
        return object;
    }

    return {
        getInstance: function() {
            if (!instance) {
                instance = createInstance();
            }
            return instance;
        }
    };
})();

const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();

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

工厂模式

  • 是什么
    • 提供一个接口,创建对象实例,但将具体创建逻辑推迟到子类。
  • 怎么使用
    • 创建一个工厂类,包含一个创建对象的方法,该方法根据输入返回不同的对象。
  • 应用场景
    • 当对象的创建逻辑复杂且多样化时,如动态创建不同类型的UI组件。
  • 例子
    • 在React中,可以有一个组件工厂,动态根据配置创建不同的UI组件。
class Button {
    constructor(label) {
        this.label = label;
    }
    
    render() {
        console.log(`<button>${this.label}</button>`);
    }
}

class Input {
    constructor(placeholder) {
        this.placeholder = placeholder;
    }
    
    render() {
        console.log(`<input placeholder="${this.placeholder}" />`);
    }
}

class ComponentFactory {
    static createComponent(type, config) {
        switch(type) {
            case 'button':
                return new Button(config.label);
            case 'input':
                return new Input(config.placeholder);
            default:
                throw new Error('Unknown component type');
        }
    }
}

const button = ComponentFactory.createComponent('button', { label: 'Click Me' });
const input = ComponentFactory.createComponent('input', { placeholder: 'Enter text' });

button.render(); // <button>Click Me</button>
input.render(); // <input placeholder="Enter text" />

观察者模式

  • 是什么
    • 定义对象间的一种一对多的依赖关系,当一个对象状态改变时,所有依赖对象都会收到通知并自动更新。
  • 怎么使用
    • 定义一个被观察者和多个观察者,被观察者在状态变化时通知所有观察者。
  • 应用场景
    • 在事件驱动的编程中,特别是UI的更新。
  • 例子
    • JavaScript中的事件处理机制,React中的状态管理。
class Subject {
    constructor() {
        this.observers = [];
    }
    
    addObserver(observer) {
        this.observers.push(observer);
    }
    
    removeObserver(observer) {
        this.observers = this.observers.filter(obs => obs !== observer);
    }
    
    notifyObservers() {
        this.observers.forEach(observer => observer.update());
    }
}

class Observer {
    update() {
        console.log('Observer updated');
    }
}

const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();

subject.addObserver(observer1);
subject.addObserver(observer2);

subject.notifyObservers(); // Observer updated, Observer updated

装饰者模式

  • 是什么
    • 动态地给对象添加职责的设计模式。
  • 怎么使用
    • 创建一个装饰者类,包裹原始类并添加新的功能。
  • 应用场景
    • 需要在不修改原类代码的情况下,动态扩展类的功能。
  • 例子
    • 在React中,可以使用高阶组件(HOC)来扩展现有组件的功能。
class Component {
    render() {
        console.log('Component render');
    }
}

class Decorator {
    constructor(component) {
        this.component = component;
    }
    
    render() {
        this.component.render();
        this.decorate();
    }
    
    decorate() {
        console.log('Decorated render');
    }
}

const component = new Component();
const decoratedComponent = new Decorator(component);

decoratedComponent.render(); 
// Component render
// Decorated render

策略模式

  • 是什么
    • 策略模式是一种行为设计模式,定义了一系列算法,将每个算法封装起来,并使它们可以互换。策略模式让算法独立于使用它的客户而变化。
  • 怎么使用
    • 定义一个策略接口,然后创建实现该接口的具体策略类。在使用策略的类中维护一个对策略对象的引用,并根据需要动态改变策略。
  • 应用场景
    • 当有多种算法可以实现相同的任务,并且需要在不同的条件下动态选择具体算法时。
  • 例子
    • 在前端开发中,可以使用策略模式来实现不同的排序算法,根据用户的选择动态切换。
class SortingStrategy {
    sort(data) {
        throw new Error('This method should be overridden');
    }
}

// 具体策略类:冒泡排序
class BubbleSort extends SortingStrategy {
    sort(data) {
        console.log('Sorting using bubble sort');
        // 冒泡排序算法实现
        for (let i = 0; i < data.length; i++) {
            for (let j = 0; j < data.length - i - 1; j++) {
                if (data[j] > data[j + 1]) {
                    [data[j], data[j + 1]] = [data[j + 1], data[j]];
                }
            }
        }
        return data;
    }
}

// 具体策略类:快速排序
class QuickSort extends SortingStrategy {
    sort(data) {
        console.log('Sorting using quick sort');
        // 快速排序算法实现
        if (data.length <= 1) return data;
        let pivot = data[Math.floor(data.length / 2)];
        let left = [];
        let right = [];
        for (let i = 0; i < data.length; i++) {
            if (i !== Math.floor(data.length / 2)) {
                data[i] < pivot ? left.push(data[i]) : right.push(data[i]);
            }
        }
        return [...this.sort(left), pivot, ...this.sort(right)];
    }
}

// 使用策略的上下文类
class Sorter {
    constructor(strategy) {
        this.strategy = strategy;
    }

    setStrategy(strategy) {
        this.strategy = strategy;
    }

    sort(data) {
        return this.strategy.sort(data);
    }
}

// 客户端代码
const sorter = new Sorter(new BubbleSort());
let data = [5, 3, 8, 4, 2];

console.log('Original data:', data);

data = sorter.sort(data);
console.log('Sorted data:', data);

sorter.setStrategy(new QuickSort());
data = [5, 3, 8, 4, 2];

console.log('Original data:', data);

data = sorter.sort(data);
console.log('Sorted data:', data);

代理模式

  • 是什么
    • 代理模式是一种结构型设计模式,允许一个对象(代理)控制对另一个对象(目标对象)的访问。代理模式通常用于延迟处理、控制访问、日志记录、缓存等。
  • 怎么使用
    • 创建一个代理类,代理类包含对目标对象的引用,并实现与目标对象相同的接口。在代理类中,可以在调用目标对象的方法之前或之后添加额外的功能。
  • 应用场景
    • 当需要在访问某个对象之前进行额外的操作(如权限检查、延迟初始化、性能优化)时,可以使用代理模式。
  • 例子
    • 在前端开发中,可以使用代理模式来实现对API请求的缓存。
// 目标对象
class APIService {
    fetchData() {
        console.log('Fetching data from the API');
        return new Promise((resolve) => {
            setTimeout(() => {
                resolve('Data from API');
            }, 1000);
        });
    }
}

// 代理对象
class APIServiceProxy {
    constructor() {
        this.apiService = new APIService();
        this.cache = null;
    }

    async fetchData() {
        if (this.cache) {
            console.log('Returning cached data');
            return Promise.resolve(this.cache);
        }

        console.log('Fetching data through proxy');
        this.cache = await this.apiService.fetchData();
        return this.cache;
    }
}

// 客户端代码
(async () => {
    const apiProxy = new APIServiceProxy();

    // 第一次调用,应该从API获取数据
    let data = await apiProxy.fetchData();
    console.log(data); // Output: Data from API

    // 第二次调用,应该从缓存获取数据
    data = await apiProxy.fetchData();
    console.log(data); // Output: Data from API (cached)
})();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值