从0开始学前端 第六十课:JavaScript设计模式

第六十课:JavaScript设计模式

学习目标

在本节课程中,我们的目标是了解和掌握以下几种常见的JavaScript设计模式:

  1. 单例模式(Singleton Pattern)
  2. 观察者模式(Observer Pattern)
  3. 模块模式(Module Pattern)
  4. 工厂模式(Factory Pattern)

学习内容

1. 单例模式(Singleton Pattern)

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

  • 代码示例

    var Singleton = (function () {
      var instance;
      
      function createInstance() {
        var object = new Object("I am the instance");
        return object;
      }
      
      return {
        getInstance: function () {
          if (!instance) {
            instance = createInstance();
          }
          return instance;
        }
      };
    })();
    
    var instance1 = Singleton.getInstance();
    var instance2 = Singleton.getInstance();
    console.log(instance1 === instance2); // true
    
  • 预计输出true,因为instance1instance2都指向同一个实例。

2. 观察者模式(Observer Pattern)

  • 概念:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。

  • 代码示例

    function Subject() {
      this.observers = []; // 观察者列表
    }
    
    Subject.prototype = {
      subscribe: function (fn) {
        this.observers.push(fn);
      },
      unsubscribe: function (fnToRemove) {
        this.observers = this.observers.filter(fn => {
          if (fn !== fnToRemove) return fn;
        });
      },
      fire: function () {
        this.observers.forEach(fn => {
          fn.call();
        });
      }
    };
    
    const subject = new Subject();
    
    function observer1() {
      console.log("Observer 1 Firing!");
    }
    
    function observer2() {
      console.log("Observer 2 Firing!");
    }
    
    subject.subscribe(observer1);
    subject.subscribe(observer2);
    subject.fire();
    
  • 预计输出

    Observer 1 Firing!
    Observer 2 Firing!
    

3. 模块模式(Module Pattern)

  • 概念:创建私有变量和函数,同时暴露出一个公开的接口。

  • 代码示例

    var ShoppingCart = (function () {
      var basket = [];
      
      return {
        addItem: function (item) {
          basket.push(item);
        },
        getItemCount: function () {
          return basket.length;
        },
        getTotal: function () {
          return basket.reduce((total, item) => {
            return total + item.price;
          }, 0);
        }
      };
    })();
    
    ShoppingCart.addItem({ item: "bread", price: 0.5 });
    ShoppingCart.addItem({ item: "butter", price: 0.3 });
    console.log(ShoppingCart.getItemCount()); // 2
    console.log(ShoppingCart.getTotal()); // 0.8
    
  • 预计输出

    2
    0.8
    

4. 工厂模式(Factory Pattern)

  • 概念:使用一个创建对象的接口,但由子类决定实例化的类是哪一个。工厂方法让类的实例化推迟到子类中进行。

  • 代码示例

    function Car(options) {
      this.doors = options.doors || 4;
      this.state = options.state || "brand new";
      this.color = options.color || "silver";
    }
    
    function Truck(options) {
      this.state = options.state || "used";
      this.wheelSize = options.wheelSize || "large";
      this.color = options.color || "blue";
    }
    
    function VehicleFactory()  VehicleFactory.prototype.vehicleClass = Car;
    VehicleFactory.prototype.createVehicle = function (options) {
      if (options.vehicleType === "car") {
        this.vehicleClass = Car;
      } else {
        this.vehicleClass = Truck;
      }
      return new this.vehicleClass(options);
    };
    
    var carFactory = new VehicleFactory();
    var car = carFactory.createVehicle({
      vehicleType: "car",
      color: "yellow",
      doors: 2
    });
    
    console.log(car instanceof Car); // true
    console.log(car); // Car { doors: 2, state: 'brand new', color: 'yellow' }
    
  • 预计输出

    true
    Car { doors: 2, state: 'brand new', color: 'yellow' }
    

课后练习

练习1:单例模式

创建一个名为DatabaseManager的单例,它应该包含connect方法,该方法打印出连接到数据库的消息。确保无论你尝试创建多少次DatabaseManager的实例,它都只会给你一个实例。

练习2:观察者模式

实现一个简单的事件管理器,允许你订阅事件、取消订阅事件以及触发事件。

练习3:模块模式

创建一个模块User,它有私有变量userCount,以及公开的方法addUsergetUserCountaddUser方法增加userCount的值,getUserCount返回当前的userCount

练习4:工厂模式

使用工厂模式创建两种类型的交通工具:自行车和汽车。每种交通工具都应该接受不同的参数,比如自行车的wheelType和汽车的fuelType

解析

练习1解析:
var DatabaseManager = (function () {
  var instance;
  
  function createInstance() {
    var object = new Object("I am the instance");
    return object;
  }
  
  return {
    getInstance: function () {
      if (!instance) {
        instance = createInstance();
      }
      return instance;
    }
  };
})();

var db1 = DatabaseManager.getInstance();
var db2 = DatabaseManager.getInstance();
console.log(db1 === db2); // true
练习2解析:
function EventManager() {
  this.events = {};
}

EventManager.prototype = {
  subscribe: function (event, fn) {
    if (!this.events[event]) {
      this.events[event] = [];
    }
    this.events[event].push(fn);
  },
  unsubscribe: function (event, fnToRemove) {
    if (this.events[event]) {
      this.events[event] = this.events[event].filter(fn => fn !== fnToRemove);
    }
  },
  trigger: function (event) {
    if (this.events[event]) {
      this.events[event].forEach(fn => {
        fn.call();
      });
    }
  }
};
练习3解析:
var User = (function () {
  var userCount = 0;
  
  return {
    addUser: function () {
      userCount++;
    },
    getUserCount: function () {
      return userCount;
    }
  };
})();

User.addUser();
User.addUser();
console.log(User.getUserCount()); // 2
练习4解析:
function VehicleFactory()VehicleFactory.prototype.createVehicle = function (options) {
  switch (options.vehicleType) {
    case "car":
      return new Car(options);
    case "bike":
      return new Bike(options);
    default:
      return null;
  }
};

function Car(options) {
  this.fuelType = options.fuelType || "gasoline";
}

function Bike(options) {
  this.wheelType = options.wheelType || "standard";
}

var factory = new VehicleFactory();
var car = factory.createVehicle({
  vehicleType: "car",
  fuelType: "diesel"
});

var bike = factory.createVehicle({
  vehicleType: "bike",
  wheelType: "mountain"
});

console.log(car instanceof Car); // true
console.log(bike instanceof Bike); // true

通过完成这些练习,你将能够加深对不同设计模式的理解,并学会如何在JavaScript中实现它们。


章节目录
第六十一课:前端性能优化

  • 12
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值