// 装饰器模式(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()