设计模式-装饰器模式

// 装饰器模式(Decorator Pattern)通过包装一个对象来实现一个具有原对象相同接口的新对象。
// 装饰器模式可以在不改变原对象结构的情况下添加扩展功能。它比通过创建子类来扩展功能更灵活。

// 购买汽车的时候,可以要求4S店添加各种配件,比如加装汽车导航,加装音响系统等。
// 下面的代码是采用子类继承来实现加装各种配件的功能。


/** 原型继承的方法*/
// function extend(subClass, superClass) {
//   var F = function() {}
//   F.prototype = superClass.prototype
//   subClass.prototype = new F()
//   subClass.prototype.constructor = subClass

//   subClass.superClass = superClass.prototype
//   if (superClass.prototype.constructor == Object.prototype.constructor) {
//     superClass.prototype.constructor = superClass
//   }
// }

// function Car() {}

// Car.prototype = {
//   selfCheck: function() {
//     return '奥迪A8 2017款 A8L 40 TFSI舒适型'
//   },
//   drive: function() {
//     console.log('我有一只小毛驴,我从来也不骑')
//   },
//   getPrice: function() {
//     return 878900
//   }
// }

// function CarWithNav() {}
// extend(CarWithNav, Car)

// CarWithNav.prototype.selfCheck = function() {
//   return CarWithNav.superClass.selfCheck() + ' 加装奥迪智能汉语语音导航系统'
// }

// CarWithNav.prototype.drive = function() {
//   CarWithNav.superClass.drive()
//   console.log('奥迪智能汉语语音导航系统开始为您导航')
// }

// CarWithNav.prototype.getPrice = function() {
//   return CarWithNav.superClass.getPrice() + 1000
// }

// function CarWithAudio() {}
// extend(CarWithAudio, Car)

// CarWithAudio.prototype.selfCheck = function() {
//   return CarWithAudio.superClass.selfCheck() + ' 加装Bang&Olufsen高级音响系统'
// }

// CarWithAudio.prototype.openAudio = function() {
//   console.log('Bang&Olufsen高级音响系统已经启动,开始播放歌曲《小毛驴》...')
// }

// CarWithAudio.prototype.getPrice = function() {
//   return CarWithAudio.superClass.getPrice() + 5000
// }


// var car1 = new CarWithNav()
// console.log(car1.selfCheck())
// console.log(car1.getPrice())
// car1.drive()
// var car2 = new CarWithAudio()
// console.log(car2.selfCheck())
// console.log(car2.getPrice())
// car2.drive()
// car2.openAudio()


// 在上面的代码中,每一个配件都需要创建一个子类,此外配件之间的组合也要创建子类,n种配件将会有2^n - 1种子类。
// 这显然是不可接受的。
// 装饰者模式可以很好的解决这个问题。
// 请利用装饰者模式完善以下代码,确保输出结果是正确的。

function extend(subClass, superClass) {
  var F = function() {}
  F.prototype = superClass.prototype
  subClass.prototype = new F()
  subClass.prototype.constructor = subClass

  subClass.superClass = superClass.prototype
  if (superClass.prototype.constructor == Object.prototype.constructor) {
    superClass.prototype.constructor = superClass
  }
}

function Car() {}

Car.prototype = {
  selfCheck: function() {
    return '奥迪A8 2017款 A8L 40 TFSI舒适型'
  },
  drive: function() {
    console.log('我有一只小毛驴,我从来也不骑')
  },
  getPrice: function() {
    return 878900
  }
}

function CarDecorator(car) {
  // 请完善代码
  this.car = car; 
}

CarDecorator.prototype = {
  selfCheck: function() {
    // 请完善代码
    this.car.selfCheck();
  },
  drive: function() {
    // 请完善代码
    this.car.drive();
  },
  getPrice: function() {
    // 请完善代码
    this.car.getPrice();
  }
}

var NavDecorator = function(car) {
  // 请完善代码
  this.car = car;
}

extend(NavDecorator, CarDecorator)

NavDecorator.prototype.selfCheck = function() {
  // 请完善代码
  return this.car.selfCheck() + ' 加装奥迪智能汉语语音导航系统';
}

NavDecorator.prototype.drive = function() {
  // 请完善代码
  this.car.drive()
  console.log('奥迪智能汉语语音导航系统开始为您导航')
}

NavDecorator.prototype.getPrice = function() {
  return this.car.getPrice() + 2000
}

var AudioDecorator = function(car) {
  // 请完善代码
  this.car = car;
}

extend(AudioDecorator, CarDecorator)

AudioDecorator.prototype.selfCheck = function() {
  // 请完善代码
  return this.car.selfCheck() + ' 加装Bang&Olufsen高级音响系统'

}

AudioDecorator.prototype.openAudio = function() {
  // 请完善代码
  console.log('Bang&Olufsen高级音响系统已经启动,开始播放歌曲《小毛驴》...')
}

AudioDecorator.prototype.getPrice = function() {
  return this.car.getPrice() + 5000
}


var car = new Car()
car = new NavDecorator(car)
car = new AudioDecorator(car)

// 奥迪A8 2017款 A8L 40 TFSI舒适型 加装奥迪智能汉语语音导航系统 加装Bang&Olufsen高级音响系统
console.log(car.selfCheck())

// 885900
console.log(car.getPrice())

// 我有一只小毛驴,我从来也不骑
// 奥迪智能汉语语音导航系统开始为您导航
car.drive()

// Bang&Olufsen高级音响系统已经启动,开始播放歌曲《小毛驴》...
car.openAudio()

 

posted @ 2020-08-07 22:17  slivens  阅读(206)  评论(1)    收藏  举报