I have a JavaScript MVC design, implemented using prototypes, where different items may be displayed in different ways as decided by the controller. For example an 'Event' item may be displayed with the views ViewTabs
or ViewSimple
. Class hierarchy:
ViewBase
- ViewTabs
-- EventViewTabs, which implements EventViewTabs.Validate
- ViewSimple
-- EventViewSimple, which implements EventViewSimple.Validate
Deciding whether to use EventViewTabs
or EventViewSimple
is done by a EventController
. My problem is: I have a Validate
method for checking inputs from the Event
views, but this method is identical for the EventViewTabs
and the EventViewSimple
views. Where should I put Validate
in order to avoid duplication? I cannot put it in ViewBase
, as other items (e.g. User
) also inherit from this class.
Seems I need multiple inheritance for this, but is there a smarter way to do it? I have a feeling I'm overlooking something obvious.
Basically your validator could be tailor-made with the type it has to work with. In UML, it's called composition. I figure out your code as follows:
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();
}
Your could abstract up both types to a base EventView
, which could expose this.validator
.
Your instance of EventController
will call:
var simple = new EventViewSimple();
simple.validator.validate();
var tabs = new EventViewTabs();
tabs.validator.validate();
Whatever the EventView
instance, they implement their own specific validator that can be called in a generic way.