美文网首页让前端飞Web前端之路
开发人员都应该了解的 7 种 JavaScript 设计模式

开发人员都应该了解的 7 种 JavaScript 设计模式

作者: 前端_java爱好者 | 来源:发表于2020-07-01 16:15 被阅读0次

    开发人员将 JavaScript 设计模式作为解决问题的模板是很合适的,但并不是说这些模式可以代替开发人员的工作。

    通过设计模式,我们可以将许多开发人员的经验结合起来,以优化过的方式来构造代码,从而解决我们所面对的问题。设计模式还提供了用于描述问题解决方案的通用词汇表,而不是去枯燥地描述代码的语法和语义。

    JavaScript 设计模式可帮助开发人员编写出井井有条、美观且结构合理的代码。尽管设计模式很容易重用,但它们并不是要取代开发人员的工作;它们是开发人员的支持与辅助,提供了与特定应用程序无关的通用解决方案,从而尽量避免那些可能导致 Web 应用程序的开发工作出现重大问题的小漏洞。

    与临时方案相比,它们消除了不必要的重复,从而缩减了代码库的整体大小,并让我们的代码更加健壮。

    在本文中,我将探讨 7 种最出色和最受欢迎的 JavaScript 设计模式,这些模式主要归为以下三类:创作设计模式、结构设计模式和行为设计模式。

    1、构造函数设计模式

    这是一种特殊的方法,用于在分配内存后初始化新创建的对象。由于 JavaScript 一般来说是面向对象的,所以它打交道最多的就是对象。于是我打算深入研究对象构造函数。在 JavaScript 中创建新对象有三种方法可用。

    以下创建构造函数设计模式的一种方法。

     // 创建一个新的空对象
     var newObject = {};
     // 创建一个新的空对象
     var newObject = Object.create(Object.prototype);
     var newObject = newObject();
    

    要访问函数的属性,你需要初始化对象。

    const object = new ConstructorObject();
    

    上面的 new 关键字告诉 JavaScript,一个 constructorObject 应该充当一个构造函数。这个设计模式并不支持继承。更多细节可以参考这里

    2、原型模式

    原型模式是基于原型继承的。在这种模式中,被创建的对象充当其他对象的原型。实际上,原型(prototype)是被创建的每个对象构造函数的蓝图。

    示例:

     var myCar= {
     name:"Ford Escort",
     brake:function(){
     console.log("Stop! I am applying brakes");
     }
     Panic : function (){
     console.log ( "wait. how do you stop thuis thing?")
     }
     }
     // 使用 object create 实个新的例化一 car
     var yourCar= object.create(myCar);
     // 现在它就是另一个的原型了
     console.log (yourCar.name);]
    

    3、模块设计模式

    模块(module)设计模式对原型模式做了一些改进。模块模式设置了不同类型的修饰符(私有和公共)。你可以创建相似的函数或属性而不会发生冲突。我们还可以灵活地公开重命名函数。这个设计模式的一个缺陷是无法覆盖(override)外部环境中创建的函数。

    示例:

    function AnimalContainter () {
     const container = [];
     function addAnimal (name) {
     container.push(name);
     }
     function getAllAnimals() {
     return container;
     }
     function removeAnimal(name) {
     const index = container.indexOf(name);
     if(index < 1) {
     throw new Error('Animal not found in container');
     }
     container.splice(index, 1)
     }
     return {
     add: addAnimal,
     get: getAllAnimals,
     remove: removeAnimal
     }
     }
     const container = AnimalContainter();
     container.add('Hen');
     container.add('Goat');
     container.add('Sheep');
     console.log(container.get()) //Array(3) ["Hen", "Goat", "Sheep"]
     container.remove('Sheep')
     console.log(container.get()); //Array(2) ["Hen", "Goat"]
    

    4、单例模式

    在仅需要创建一个实例的情况下(例如一个数据库连接),这个模式是必需的。在这个模式中,只能在关闭连接时创建一个实例,或者在打开新实例之前必须关闭已有的实例。此模式也称为严格模式,它的一个缺点是测试时的体验很差,因为它隐藏的依赖项对象很难挑出来进行测试。

    示例:

     function DatabaseConnection () {
     let databaseInstance = null;
     // 追踪特定时间创建实例的数量
     let count = 0;
     function init() {
     console.log(`Opening database #${count + 1}`);
     // 现在执行操作
     }
     function createIntance() {
     if(databaseInstance == null) {
     databaseInstance = init();
     }
     return databaseInstance;
     }
     function closeIntance() {
     console.log('closing database');
     databaseInstance = null;
     }
     return {
     open: createIntance,
     close: closeIntance
     }
     }
     const database = DatabseConnection();
     database.open(); //Open database #1
     database.open(); //Open database #1
     database.open(); //Open database #1
     database.close(); //close database
    

    5、工厂模式

    这个模式的创新之处在于,它不需要构造函数就能创建对象。它提供了用于创建对象的通用接口,我们可以在其中指定要创建的工厂(factory)对象的类型。这样一来,我们只需指定对象,然后工厂会实例化并返回这个对象供我们使用。当对象组件设置起来很复杂,并且我们希望根据所处的环境轻松地创建不同的对象实例时,使用工厂模式就是很明智的选择。在处理许多共享相同属性的小型对象,以及创建一些需要解耦的对象时也可以使用工厂模式。

    示例:

    // Dealer A
     DealerA = {};
     DealerA.title = function title() {
     return "Dealer A";
     };
     DealerA.pay = function pay(amount) {
     console.log(
     `set up configuration using username: ${this.username} and password: ${
     this.password
     }`
     );
     return `Payment for service ${amount} is successful using ${this.title()}`;
     };
     //Dealer B
     DealerB = {};
     DealerB.title = function title() {
     return "Dealer B";
     };
     DealerB.pay = function pay(amount) {
     console.log(
     `set up configuration using username: ${this.username}
     and password: ${this.password}`
     );
     return `Payment for service ${amount} is successful using ${this.title()}`;
     };
     //@param {*} DealerOption
     //@param {*} config
     function DealerFactory(DealerOption, config = {}) {
     const dealer = Object.create(dealerOption);
     Object.assign(dealer, config);
     return dealer;
     }
     const dealerFactory = DealerFactory(DealerA, {
     username: "user",
     password: "pass"
     });
     console.log(dealerFactory.title());
     console.log(dealerFactory.pay(12));
     const dealerFactory2 = DealerFactory(DealerB, {
     username: "user2",
     password: "pass2"
     });
     console.log(dealerFactory2.title());
     console.log(dealerFactory2.pay(50));
    

    6、观察者模式

    观察者(observer)设计模式在许多对象同时与其他对象集通信的场景中用起来很方便。在观察者模式中不会在状态之间发生不必要的事件 push 和 pull;相比之下,所涉及的模块仅会修改数据的当前状态。

    示例:

    function Observer() {
     this.observerContainer = [];
     }
     Observer.prototype.subscribe = function (element) {
     this.observerContainer.push(element);
     }
     // 下面是从 container 中移除一个元素
     Observer.prototype.unsubscribe = function (element) {
     const elementIndex = this.observerContainer.indexOf(element);
     if (elementIndex &gt; -1) {
     this.observerContainer.splice(elementIndex, 1);
     }
     }
     /**
     * we notify elements added to the container by calling
     * each subscribed components added to our container
     */
     Observer.prototype.notifyAll = function (element) {
     this.observerContainer.forEach(function (observerElement) {
     observerElement(element);
     });
     }
    

    7、命令模式 最后介绍的是命令(command)模式。命令设计模式将方法调用、操作或请求封装到单个对象中,以便我们可以自行传递方法调用。命令设计模式让我们可以从任何正在执行的命令中发出命令,并将责任委托给与之前不同的对象。这些命令以 run() 和 execute() 格式显示。

    (function(){
     var carManager = {
     // 请求的信息
     requestInfo: function( model, id ){
     return "The information for " + model + " with ID " + id + " is foo bar";
     },
     // 现在购买这个 car
     buyVehicle: function( model, id ){
     return "You have successfully purchased Item " + id + ", a " + model;
     },
     // 现在 arrange viewing
     arrangeViewing: function( model, id ){
     return "You have successfully booked a viewing of " + model + " ( " + id + " ) ";
     }
     };
     })();
    

    小结

    对于 JavaScript 开发人员来说,使用设计模式的好处很多。设计模式的一些主要优点包括提升项目的可维护性,还能减少开发周期中不必要的工作。JavaScript 设计模式可以为复杂的问题提供解决方案,提升开发速度并提高生产率。但并不能说这些设计模式就可以让开发人员偷懒了。

    如果你觉得这篇文章不错,请别忘记点个关注哦~😊

    相关文章

      网友评论

        本文标题:开发人员都应该了解的 7 种 JavaScript 设计模式

        本文链接:https://www.haomeiwen.com/subject/ldchqktx.html