前边介绍了简单工厂模式和组合工厂模式,其实都换汤不换药,这里再介绍一种抽象工厂模式。抽象工厂模式常出现在后端开发中,比如Java,可以使用abstract关键字来定义一个抽象类,或者组装成一个抽象工厂。
在前端中,我们也可以使用现有的语法来组装一个抽象工厂。
- 抽象类中的方法不能直接调用,子类必须先实现其方法才能调用
- 可以在抽象类中定义一套规范,供子类去继承实现
抽象类
//首先我们需要先定义一个模板
function MyCar(color, price) {
this.color = color;
this.price = price;
}
MyCar.prototype.run = function () {
throw new Error("不能直接调用抽象方法");
}
//定义工厂
var BMW = function (color, price) {
MyCar.call(this, color, price);
}
BMW.prototype = new MyCar('white', 123456);
//如果此时你这样使用就会报错
new BMW('white', 12345).run(); //Uncaught Error: 不能直接调用抽象方法
//所以此时就不这样 BMW.prototype = new MyCar('white', 123456);
BMW.prototype = {
run: function () { //重写run方法
console.log(`the ${this.color} BMW is running`);
}
}
new BMW('red', 1234).run(); //输出 the red BMW is running
以上就实现了一个抽象类,抽象类中的方法子类必须重写,否则不能使用。而抽象工厂,则是定义一批这样的抽象类,更具需要提供给子类去继承和重写。
抽象工厂
var Factory = function (type) {
var _type = {
Bus: function(no) {
this.no = no;
},
Car: function (color, price) {
this.color = color;
this.price = price;
}
};
_type.Bus.prototype.getNo = function () { throw new Error("不能直接调用抽象方法"); }
_type.Car.prototype.run = function () { throw new Error("不能直接调用抽象方法"); }
//...
return (function () {
if (_type[type]) {
return _type[type];
} else {
throw new Error("不存在的类型");
}
}());
}
//子类继承
var BMW = function (color, price) {
Factory('Car').call(this, color, price);
}
//同样的道理,不能使用 BMW.prototype = new MyCar('white', 123456); 这种方式继承,而是必须重写内部方法,否则使用其方法的时候会抛出异常
//应该这样
BMW.prototype.run = function () {
console.log(`the ${this.color} BMW is running`);
}
//使用
new BMW('green', 13579).run();
网友评论