基于原型链的Javascript多重继承
我有一个JavaScriptMVC设计,使用原型实现,其中不同的项目可以按照控制器的决定以不同的方式显示。例如,“事件”项可能与视图基于原型链的Javascript多重继承,javascript,model-view-controller,multiple-inheritance,prototypal-inheritance,Javascript,Model View Controller,Multiple Inheritance,Prototypal Inheritance,我有一个JavaScriptMVC设计,使用原型实现,其中不同的项目可以按照控制器的决定以不同的方式显示。例如,“事件”项可能与视图viewtab或ViewSimple一起显示。类层次结构: ViewBase - ViewTabs -- EventViewTabs, which implements EventViewTabs.Validate - ViewSimple -- EventViewSimple, which implements EventViewSimple.Validate
viewtab
或ViewSimple
一起显示。类层次结构:
ViewBase
- ViewTabs
-- EventViewTabs, which implements EventViewTabs.Validate
- ViewSimple
-- EventViewSimple, which implements EventViewSimple.Validate
决定是使用eventviewtab
还是EventViewSimple
由EventController
完成。我的问题是:我有一个Validate
方法来检查Event
视图中的输入,但是这个方法对于EventViewTabs
和EventViewSimple
视图是相同的。我应该将验证放在哪里以避免重复?我无法将其放入ViewBase
,因为其他项(例如User
)也从此类继承
看起来我需要多重继承,但是有没有更聪明的方法呢?我有一种感觉,我忽略了一些显而易见的东西。一种方法是使用mixin来添加其他行为(这是ruby方法,react.js和react.rb也使用这种方法)。您可以在谷歌上搜索javascript+mixin,并找到一些类似这样的优秀教程:
对于您的特定情况,validate
(或者可能是validator
)将是mixin。一种方法是使用mixin添加其他行为(这是ruby方法,react.js和react.rb也使用这种方法),您可以在谷歌上搜索javascript+mixin,并找到一些类似以下的优秀教程:
对于您的特定情况,validate
(或者可能是validator
)将是mixin。为什么不这样做:
视距
也考虑使用构造函数来继承继承,请参阅< /P> < P> >为什么不做这样的事情:
视距
也考虑使用构造函数来继承继承,请参阅
你缺少构图。继承并不是所有关于代码重用以避免复制粘贴编程的问题的答案
假设您有一个视图
基本原型:
如果希望此视图支持验证,可以在构造函数中插入验证依赖项:
function View(validator) {
this.validator = validator;
}
View.prototype = {}; // A lot of functions here
也就是说,现在任何继承视图
原型的视图都将有一个关联的验证器。换句话说:您不需要在具体视图中派生两个原型(您不需要,而且无论如何也做不到)
另一方面,就面向对象编程而言,从验证器
派生来创建视图
是没有意义的
当你说一个视图有一个验证器时,因为你用has作为动词,你说的是一个关联(一种组合形式)。或者,当您说我的主屏幕是作为视图时,我们谈论的是继承,因为特定视图也必须是视图,所以它需要基本视图的成员像视图一样工作您缺少组合。继承并不是所有关于代码重用以避免复制粘贴编程的问题的答案
假设您有一个视图
基本原型:
如果希望此视图支持验证,可以在构造函数中插入验证依赖项:
function View(validator) {
this.validator = validator;
}
View.prototype = {}; // A lot of functions here
也就是说,现在任何继承视图
原型的视图都将有一个关联的验证器。换句话说:您不需要在具体视图中派生两个原型(您不需要,而且无论如何也做不到)
另一方面,就面向对象编程而言,从验证器
派生来创建视图
是没有意义的
当你说一个视图有一个验证器时,因为你用has作为动词,你说的是一个关联(一种组合形式)。或者,当你说我的主屏幕是视图时,我们说的是继承,因为特定视图也必须是视图,所以它需要基本视图的成员像视图一样工作基本上你的验证器可以根据它必须使用的类型进行定制。在UML中,它被称为组合。我将您的代码计算如下:
function Validator {}
Validator.prototype.validate = function(arg) {
//arg is no longer inputs
return true|false; //the ultimate output along with additional information;
}
function EventViewTabsValidator() {}
EventViewTabsValidator.prototype = Object.extend(Validator.prototype); //inheritance
EventViewTabsValidator.prototype.constructor = EventViewTabsValidator; //enforce the constructor to point to your derived type
EventViewTabsValidator.prototype.validate = function() {
var inputs = $('inputs');
var param = 'do some stuff specific to EventViewTabsValidator based on the inputs';
return Validator.prototype.validate.call(this, param); //pass param, not inputs
}
function EventViewSimpleValidator() {}
EventViewSimpleValidator.prototype = Object.extend(Validator.prototype); //inheritance
EventViewSimpleValidator.prototype.constructor = EventViewSimpleValdiator; //enforce the constructor to point to your derived type
EventViewSimpleValidator.prototype.validate = function() {
var inputs = $('inputs');
var param = 'do some stuff specific to EventViewSimpleValidator based on the inputs';
return Validator.prototype.validate.call(this, param); //pass param, not inputs
}
function EventViewTabs() {
this.validator = null; //see init
}
EventViewTabs.prototype.init = function() {
this.validator = new EventViewTabsValidator();
}
function EventViewSimple() {
this.validator = null; //see init
}
EventViewSimple = function() {
this.validator = new EventViewSimpleValidator();
}
您可以将这两种类型抽象为一个基本的EventView
,它可以公开这个.validator
。
EventController
的实例将调用:
var simple = new EventViewSimple();
simple.validator.validate();
var tabs = new EventViewTabs();
tabs.validator.validate();
无论EventView
实例是什么,它们都实现了自己的特定验证器,可以以通用方式调用 基本上,您的验证器可以根据它必须使用的类型进行定制。在UML中,它被称为组合。我将您的代码计算如下:
function Validator {}
Validator.prototype.validate = function(arg) {
//arg is no longer inputs
return true|false; //the ultimate output along with additional information;
}
function EventViewTabsValidator() {}
EventViewTabsValidator.prototype = Object.extend(Validator.prototype); //inheritance
EventViewTabsValidator.prototype.constructor = EventViewTabsValidator; //enforce the constructor to point to your derived type
EventViewTabsValidator.prototype.validate = function() {
var inputs = $('inputs');
var param = 'do some stuff specific to EventViewTabsValidator based on the inputs';
return Validator.prototype.validate.call(this, param); //pass param, not inputs
}
function EventViewSimpleValidator() {}
EventViewSimpleValidator.prototype = Object.extend(Validator.prototype); //inheritance
EventViewSimpleValidator.prototype.constructor = EventViewSimpleValdiator; //enforce the constructor to point to your derived type
EventViewSimpleValidator.prototype.validate = function() {
var inputs = $('inputs');
var param = 'do some stuff specific to EventViewSimpleValidator based on the inputs';
return Validator.prototype.validate.call(this, param); //pass param, not inputs
}
function EventViewTabs() {
this.validator = null; //see init
}
EventViewTabs.prototype.init = function() {
this.validator = new EventViewTabsValidator();
}
function EventViewSimple() {
this.validator = null; //see init
}
EventViewSimple = function() {
this.validator = new EventViewSimpleValidator();
}
您可以将这两种类型抽象为一个基本的EventView
,它可以公开这个.validator
。
EventController
的实例将调用:
var simple = new EventViewSimple();
simple.validator.validate();
var tabs = new EventViewTabs();
tabs.validator.validate();
无论EventView
实例是什么,它们都实现了自己的特定验证器,可以以通用方式调用 我可能应该说得更具体一些:其他类也从ViewTabs和ViewSimple继承,所以这些类不能从EventValidator继承。不过,感谢您提供关于组合的提示。我可能应该更具体一些:其他类也从ViewTabs和ViewSimple继承,所以这些类不能从EventValidator继承。谢谢你的作文技巧。谢谢,看来这是我自己找不到的明显的解决办法!谢谢,看来这是我自己找不到的明显的解决办法!