前端开发中常用的设计模型

279 阅读4分钟

在前端开发过程中,应用程序逻辑和用户界面往往紧密耦合,这就使代码变得难以维护。而设计模型则可作为一个实践方法,帮助开发者降低复杂度、提高代码质量、可读性和可维护性。本文介绍几个在前端开发中广泛应用的设计模型,并解释它们如何能够让你的代码更加健壮且易于维护。

1. 单例模式(Singleton Pattern)

单例模式是一种仅允许实例化一个特定类并且全局都可以访问该实例的模式。最常见的应用场景之一是管理共享资源(例如HTTP请求)。理想情况下,在HHTP服务初始化时只需要创建单个实例,并在整个应用程序范围内重复使用此实例。这有助于避免不必要的网络操作和提高应用性能。

实现单例模式的方式非常简单——我们可以将构造函数的实例保存到静态属性或闭包中。请看下面的示例:

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

const singletonInstanceOne = new Singleton('This is first instance');
const singletonInstanceTwo = new Singleton('This is second instance');

// The following should be true, since only one instance has been created
console.log(singletonInstanceOne === singletonInstanceTwo); // true

console.log(singletonInstanceOne.data);

在这个例子中,我们定义了一个用于创建单例对象的类“Singleton”。同时,在该构造函数内使用静态属性Singleton.instance将第一次实例化后的结果保存下来,并确保每次调用时只返回创建好的实例。因此,由两个不同的初始化传递参数的新单例对象,仅有一个是成功生成的——the "first" instance。

2. MVVM模式(Model-View-ViewModel Pattern)

MVVM模式被设计为一种分离应用程序逻辑与用户界面设计的架构。其中,“Model”代表数据层,“ViewModel”充当胶合剂,将视图层与数据层连接起来。“View”显示操作结果。

过程中,数据绑定机制使得开发人员可以在其代码中使用少量HTML而不必编写许多BOILERPLATE HTML标记、处理DOM操作等繁琐步骤。在MVVM中,我们不再需要通过频繁增删/更新DOM节点来动态变更UI元素的状态。转而通过对ViewModel(视图模型) 中的值进行监听,将组件的状态自动反映到界面上。

下面是一个简单的MVVM模式示例,它演示了当viewModel中参数的值发生更改时如何更新视图:

class ViewModel {
    constructor() {
        this.text = 'Hello, world!';
    }
}

viewModel = new ViewModel();

// This element's text content will be bound to the "text" property in our viewModel object
const observableElement = document.createElement('div');
document.body.appendChild(observableElement);

// Define a function that updates the UI with the current value of the model.
function updateView() {
  observableElement.textContent = `${viewModel.text}`;
}

// Create a view model change handler which sets the new value and triggers an update
function setNewValue(newValue) {
    viewModel.text = newValue;
    updateView();
}

// Update the view every time the vm is updated
updateView();

setNewValue("new hello world!");

在这个素材丰富的MVVM模式实现方式中,“ViewModel”类可以存储页面所需数据。另外,我们还定义了两个函数——setNewValue_renderVue,用于新增、删除以及更新当前组件的属性。从输出内容(“New Hello World!”)可看出,修改后的文本此刻已成功绑定。而其核心原因便是:当将通过监听器更新app.currentTitle调用_watch来观察model.pos变量时,同时也在每次新值传递过程中调用了我们实现好的辅助渲染函数,最终呈现给用户的结果也就顺理成章地被优化为了新值。

3. 观察者模式(Observer Pattern)

观察者模式是一种事件驱动的同步代码实现方法。它允许在发生某些时间时调用预先定义好的函数或代码块集合,以完成想要实现的业务逻辑。该设计模型支持非阻塞通知并被视为异步API//组件可以链接服务事件,并指明当特定内容更改时应如何响应。

以下是一个使用观察者设计模式更新用户界面的示例:

class Observable {
    constructor() {
        this.observers = [];
    }

    notifyObservers(data) {
        for (let observer of this.observers) {
            observer.update(data);
        }
    }

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

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

class Observer {
    update(data) {
        console.log(`Received data: ${data}`);
    }
}

const observable = new Observable();
const observerA = new Observer();
const observerB = new Observer();

observable.addObserver(observerA);
observable.addObserver(observerB);

observable.notifyObservers('Hello, world!');

这个Observable / Observer示例包含具有触发消息传播的“Observable”类,还有两个与之关联的执行特定操作的“Observer”类。通过调用addObserver()方法并将其添加到Observabe实例的内部数组中,页面连接即建立。

4. 代理模式(Proxy Patterns)

代理模式是一个被用来控制对某个对象访问的方法。通过使用一个附加上限添加“代理”,做为原始组件项和外部逻辑之间的中介,能够更好地管理多种行为面临较大复杂度时如何消除性能瓶颈、采取正确而精确的优化方式。

示例:下方代码中创建proxy实例并调用它的查询方法时,可以标准化每次搜索所请求的URL。这样就不必在各处重复写分页过滤器或URI编码等复杂数据约定逻辑了。

const service = {
  async fetch(url) {
    return await fetch(url).then((res) => res.json());
  },
};

// Proxy sample
const urlServiceProxy = new Proxy(service, {
    apply(target, thisArg, args) {
    console.log(`Fetching data from ${args}`);
      const formattedUrl = `https://example.com/api/getData?filter=${encodeURIComponent(args[0])}&page=${encodeURIComponent(
        args[1]
      )}`;
      return target.fetch(formattedUrl);
    },
});

async function fetchData(){
    const response = await urlServiceProxy("latest post", "2");

    // Output the fetched result for testing purpose.
    console.log(response)
}

fetchData();

总结

设计模型是一项需要技术人员深入研究和掌握的艺术,其目的旨在简化庞杂的业务流程、提高相应的用户体验,并发挥JavaScript诸多所见即所得、跨平台特性中的优势。借助“单例模式(singleton pattern)”、“MVVM(model-view-viewModel)patterm)”,观察者模式(Observer Pattern)和代理模式(proxy pattern)等设计模型,可以帮助你在实际的工作中更高效开发。