基于原型链的Javascript多重继承

基于原型链的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

我有一个JavaScriptMVC设计,使用原型实现,其中不同的项目可以按照控制器的决定以不同的方式显示。例如,“事件”项可能与视图
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继承。谢谢你的作文技巧。谢谢,看来这是我自己找不到的明显的解决办法!谢谢,看来这是我自己找不到的明显的解决办法!