浅谈JavaScript设计模式

  1. 创建型模式 :该模式处理的是用于创建对象的各种机制
  • 工厂方法
  • 抽象工厂
  • 建造者
  • 原型
  • 单例
  1. 结构型模式:考虑的是对象的组成以及对象彼此之间的关系
  • 适配器
  • 桥接
  • 组合
  • 装饰器
  • 外观
  • 享元
  • 代理
  1. 行为型模式:关注的是对象之间的依赖关系以及通信
  • 解释器
  • 模板方法
  • 责任链
  • 命令
  • 迭代器
  • 中介者
  • 备忘录
  • 观察者
  • 状态
  • 策略
  • 访问者

  1. 模块模式
    var basic = {
      eniv: 'production',
      startupParam:{
        cache: 30,
        locale: 'en_US'
      },
      init: function(){
        console.log('init server')
      },
      update: function(params) {
        this.startupParam = params
           console.log(this.startupParam.cache)
           console.log('this.startupParam.locale')
      }
    }
    basic.init()      // init server
    basic.update({cache: 60, locale: 'en_UK'})      //60, en_UK

  2. 对上面的代码稍作改动,使用IIFE并返回模块接口
    var basic = (function (){
      var eniv = 'production';
      var startupParam = {
        cache: 30,
        locale: 'en_US'
      };
      return{
        init: function(){
          console.log('init server')
        },
        update: function(params) {
           this.startupParam = params
           console.log(this.startupParam.cache)
           console.log('this.startupParam.locale')
        }
      }
    })()
    basic.init()      // init server
    basic.update({cache: 60, locale: 'en_UK'})      //60,

  3. 对上面的模式再进行变形,不推荐在调用其他函数的公共函数或是公共变量的时候非得使用模块名,这种改进的模式也被称为RMP(暴露式模块模式),其背后主要的思路就是将所有的成员都定义在私有作用域中,使用指针返回一个匿名对象,该指针指向的私有功能需要公开暴露
    var basic = function() {
      var privateOne = 1;
      function privateFn() {
        console.log('private call');
      }
      var privateTwo = 2;
      function publicFn() {
        publicFnTwo();
      }
      function publicFnTwo() {
        privateFn();
      }
      function getCurrentState() {
        return 2;
        }
      return {
        setup: publicFn,
        count: publicTwo,
        increase: publicFnTwo,
        current: getCurrentState()
      }
    }()
    console.log(basic.current)    // 2
    basic.setup()  // private call


  4. 工厂模式
    function CarFactory() {}
    CarFactory.prototype.info = function() {
        console.log('info');
    }
    // 静态工厂方法
    CarFactory.make = function(type) {
        var constr = type;
        var car;
        CarFactory[constr].prototype = new CarFactory();
        car = new CarFactory[constr]();
        return car;
    }
    CarFactory.Compact = function(){
        this.doors = 4;
        this.engine_capacity = 2;
    }
    CarFactory.Sedan = function() {
        this.doors = 2;
        this.engine_capacity = 2;
    }
    CarFactory.SUV = function(){
        this.doors = 4;
        this.engine_capacity = 6;
    }
    var golf = CarFactory.make['Compact'];
    var vento = CarFactory.make['Sedan'];
    var touareg = CarFactory.make['SUV'];
    golf.info();    // info


  5. mixin模式
    mixin模式能够显著减少代码中重复出现的功能,有助于功能复用。这样你就可以将注意力放在构建实际功能上,而不是一再去重复那些可以共享的行为。
    var _ = require('underscore');
    var logger = (function () {
      var CustomLogger = {
        log: function (message) {
          console.log(message);
        }
      }
    }())
    // 需要定制的日志记录器来记录系统特定日志的对象
    var Server = (function (Logger) {
      var CustomServer = function() {
        this.init = function() {
          this.log(initial server);
        }
      }
      // 将CustomLogger的成员复制/扩展为CustomServer
      _.extend(CustomServer.prototype, Logger);
      return CustomServer;
    }(logger))
    (new Server()).init()  // initial server
    // 通过原型继承,将mixin的功能加入到对象中



    9.装饰器模式
    主要思想就是使用一个空白对象展开设计,该对象有一些基本的功能,随着设计的深入,可以使用现有的装饰器来增强该空白对象。
    // 实现最小化的BasicServer
    function BasicServer () {
      this.pid = 1;
      console.log('initial basic server');
      this.decorate_list = [];  // 空的装饰器列表
    }
    // 列出所有的装饰器
    BasicServer.decorators = {};
    // 将每个装饰器添加到BasicServer的装饰器列表中
    // 列表中的每个装饰器都会被应用到BasicServer实例
    BasicServer.decorators.reverseProxy = {
      init: function(pid){
        return pid + 1;
      }
    }
    BasicServer.decorators.servePHP = {
      init: function(pid) {
        return pid + 1;
      }
    }
    // 每次调用decorate()时,都将装饰器推入列表
    BasicServer.prototype.decorate = function(decorator) {
      this.decorate_list.push(decorator);
    }
    // init() 方法遍历所有应用于BasicServer的装饰器,在所有的装饰器上执行init()方法
    BasicServer.prototype.init = function () {
      var running_process = 0;
      var pid = this.pid;
      for(var i = 0; i < this.decorate_list.length; i++) {
        decorate_name = this.decorate_list[i];
        running_processes = BasicServer.decorators[decorate_name].init(pid);
        return running_process;
      }
    }
    // 创建提供reverseProxy代理的服务器
    var proxyServer = new BasicServer();
    proxyServer.decorate('reverseProxy');
    total_process = proxyServer.init()
    // 创建提供PHP服务的服务器
    var phpServer = new BasicServer()
    phpServer.decorate(servePHP)
    total_process = phpServer.init()



    10 观察者模式
    目标+观察者;在观察者模式中,目标保存了一个对其依赖的对象列表(称为观察者),并在自身状态发生变化时通知这些观察者,目标采用的通知方式是广播;观察者如果不想再被提醒,可以把自己从列表中移除。
    // 目标:能够添加,删除和提醒观察者目标
    var Subject = (function() {
      function Subject(){
        this.observer_list = [];
      }
      Subject.prototype.add_observer = function(obj){
        this.observer_list.push(obj)
      }
      Subject.prototype.remove_observer = function(obj) {
        for(var i = 0; i < this.observer_list.length; i++){
          if(this.observer_list[i] === obj) {
            this.observer_list.splice(i,1)
          }
        }
      }
      Subject.prototype.notify = function(){
        var args = Array.prototype.splice.call(arguments,0)
        for(var i = 0; i
          this.observer_list[i].update(args)
        }
      }
      return Subject
    })()
    // 观察者
    function Tweeter(){
      var subject = new Subject()
      this.addObserver = function(observer){
        subject.add_observer(observer)
      }
      this.removeObserver = function(observer){
        subject.remove_observer(observer)
      }
      this.fetchTweets = function fetchTweets() {
        var tweet = {
          tweet: 'this is a abserver'
        }
        subject.notify(tweet)
      }
    }
    // 添加两名观察者
    var TweetUpdater = {
      update: function() {
        console.log('update tweet')
      }
    }
    var TweetFllower = {
      update: function() {
        console.log(Fllower tweet)
      }
    }
    // 此时我们就可以通过Tweeter的接口将观察者添加到Subject中了
    var tweetApp = new Tweeter()
    tweetApp.addObserver('TweetUpdater')
    tweetApp.addObserver('TweetFllower')
    tweetApp.fetchTweets()
    tweet.removeObserver(TweetUpdater)
    tweet.removeObserver('TweetFllower')

你可能感兴趣的:(JS(ES))