Edit in JSFiddle

var Observer = {
    
    EVENTID : 0,
    listeners: {},
    addEvent : function(type, hnd){

        if(!this.listeners[type]) this.listeners[type] = {};

        var eventId = Observer.EVENTID++;
        this.listeners[type][eventId] = hnd;

        return eventId;
    },

    fireEvent : function(type){

        var handlers = this.listeners[type], eventId,
            args =  Array.prototype.slice.call(arguments);
        if(handlers.stop) return false;

        args.shift();
        for(eventId in handlers) if(handlers.hasOwnProperty(eventId)){
            if(eventId !== "stop"){
                if(!handlers[eventId].stop){
                    handlers[eventId].apply(this, args);
                }
            }
        };
    },

    removeEvent : function(type, hnd){

        if(!this.listeners[type]) return -1;

        var handlers = this.listeners[type], eventId = -1;
        if(typeof hnd === "function"){
            for(eventId in handlers) if(handlers.hasOwnProperty(f)){
                if(handlers[eventId] === hnd){
                    delete handlers[eventId];
                    break;
                }
            };
            return !handlers[eventId];
        }else{
            if(handlers[hnd]) delete handlers[hnd]
            return !handlers[hnd];
        };
    },

    stopEvent : function(type, hnd){

        if(!this.listeners[type]) return -1;
        var handlers = this.listeners[type], eventId = -1;
        if(hnd){
            if(typeof hnd === "function"){
                for(eventId in handlers) if(handlers.hasOwnProperty(f)){
                    if(handlers[eventId] === hnd){
                        handlers[eventId].stop = true;
                    }
                };
            }else{
                handlers[hnd].stop = true;
            }
        }else{
            handlers.stop = true;
        }
    },

    restoreEvent : function(type, hnd){

        if(!this.listeners[type]) return -1;

        var handlers = this.listeners[type], eventId = -1;
        if(hnd){
            if(typeof hnd === "function"){
                for(eventId in handlers) if(handlers.hasOwnProperty(f)){
                    if(handlers[eventId] === hnd){
                        handlers[eventId].stop = false;
                    }
                };
            }else{
                handlers[hnd].stop = false;
            }
        }else{
            handlers.stop = false;
        }
    },

    isEvent: function(type){

        var ret = false;
        var listeners = this.listeners[type];

        var listenersLength = function() {

            var ret = [];

            for (var evtId in listeners) ret.push(evtId);

            return ret.length;
        }();

        var handlerLength = function() {

            var ret = [];
            for (var evtId in listeners) {

                var handler = listeners[evtId];

                if (handler && handler.constructor === Function) {
                    ret.push(handler);
                }
            }

            return ret.length;
        }();

        if (listenersLength && handlerLength) {

            if (listenersLength === handlerLength) {
                ret = true;
            }
        }

        return ret;
    },

    applyObserver : function(tclass){
        for(var p in this){
            if(this[p] !== arguments.callee){
                tclass.prototype[p] = this[p];
            }
        };

        return true;
    }
};

var Interface = function() {

    var names = {};

    var _Interface = function(name, declaratives){
        return new Interface(name, declaratives);
    }

    function Interface(name, declaratives) {

        name = name && name.constructor === String ? name : null;
        declaratives = declaratives && declaratives.constructor === Object ? declaratives : null;

        if (!name) {
            throw new Error('인터페이스 이름이 정의되지 않았습니다.');
        }

        if (!declaratives) {
            throw new Error('인터페이스 선언부가 정의되지 않았습니다.');
        }

        this.propertiess = {};
        this.events = [];
        this.methods = [];

        if (names[name]) {
            throw new Error('이미 동일한 인터페이스 이름이 존재합니다.');
        }

        names[name] = name;

        var hasOwnProperty = Object.hasOwnProperty;

        var propertiess = declaratives.propertiess && declaratives.propertiess.constructor === Object ? declaratives.propertiess : null;
        var events = declaratives.events && declaratives.events.constructor === Array ? declaratives.events : null;
        var methods = declaratives.methods && declaratives.methods.constructor === Array ? declaratives.methods : null;

        if (propertiess) {

            for (var propertiesName in propertiess) {

                if (hasOwnProperty.call(propertiess, propertiesName)) {

                    var properties = propertiess[propertiesName];

                    if (!properties['get'] && !properties['set']) {
                        throw new Error('인터페이스 접근자가 선언되지 않았습니다.');
                    }

                    this.propertiess[propertiesName] = properties;
                }
            }
        }

        if (events) {

            for (var i = 0; i < events.length; i++) {

                var eventName = events[i];

                if (!(eventName && eventName.constructor === String)) {
                    throw new Error('인터페이스 이벤트 선언은 (String) 타입으로 선언되어야합니다.');
                }

                this.events.push(eventName);
            }
        }

        if (methods) {

            for (var y = 0; y < methods.length; y++) {

                var methodName = methods[y];

                if (!(methodName && methodName.constructor === String)) {
                    throw new Error('인터페이스 메서드 선언은 (String) 타입으로 선언되어야합니다.');
                }

                this.methods.push(methodName);
            }
        }
    }

    _Interface.ensureImplement = function(_class, _interfaces){

        _class = _class || null;
        _interfaces = [].slice.call(arguments, 1);

        if (!_class) {
            throw new Error('구현 클래스가 정의되지 않았습니다.');
        }

        if (!_interfaces.length) {
            throw new Error('인터페이스가 정의되지 않았습니다.');
        }

        for (var i = 0; i < _interfaces.length; i++){

            var _interface = _interfaces[i];

            if (!(_interface instanceof Interface)){
                throw new Error('인터페이스가 정의되지 않았습니다.');
            }

            var propertiess = _interface.propertiess && _interface.propertiess.constructor === Object ? _interface.propertiess : null;
            var events = _interface.events && _interface.events.constructor === Array ? _interface.events : null;
            var methods = _interface.methods && _interface.methods.constructor === Array ? _interface.methods : null;

            if (propertiess){

                for (var propertiesName in propertiess) {

                    var properties = propertiess[propertiesName];

                    var firstFnName = propertiesName.substr(0, 1).toUpperCase();
                    var lastFnName = propertiesName.substr(1);

                    if (properties['get']) {

                        if (!_class['get' + firstFnName + lastFnName]) {
                            throw new Error(_class.constructor + ' 구현 클래스에서 인터페이스 속성(' + 'get' + firstFnName + lastFnName + ')이 구현되지 않았습니다.');
                        }
                    }

                    if (properties['set']){

                        if (!_class['set' + firstFnName + lastFnName]) {
                            throw new Error(_class.constructor + ' 구현 클래스에서 인터페이스 속성(' + 'set' + firstFnName + lastFnName + ')이 구현되지 않았습니다.');
                        }
                    }
                }
            }

            if (events){

                for (var y = 0; y < events.length; y++) {

                    var eventName = events[y];

                    if (!Observer.isEvent(eventName)) {
                        throw new Error(_class.constructor + ' 구현 클래스에서 인터페이스 이벤트(' + eventName + ')가 구현되지 않았습니다.');
                    }
                }
            }

            if (methods){

                for (var z = 0; z < methods.length; z++) {

                    var methodName = methods[z];
                    var method = _class[methodName];

                    if (!method || method.constructor !== Function) {
                        throw new Error(_class.constructor + ' 구현 클래스에서 인터페이스 메서드(' + methodName + ')가 구현되지 않았습니다.');
                    }
                }
            }
        }

        return _class;
    }

    return _Interface;

}();

// DB 인터페이스
var DBInterface = Interface('DBInterface', {
    methods: ['connect', 'disconnect']
});

// MSSQLAPI 구현 클래스
function MSSqlAPIClass(){}

MSSqlAPIClass.prototype.connect = function(){
    return 'connect';
}

MSSqlAPIClass.prototype.disconnect = function(id){
    return 'disconnect';
}

// OracleAPI 구현 클래스
function OracleAPIClass(){}

OracleAPIClass.prototype.connect = function(){
    return 'connect';
}

OracleAPIClass.prototype.disconnect = function(id){
    return 'disconnect';
}

// MySqlAPI 구현 클래스
function MySqlAPIClass(){}

MySqlAPIClass.prototype.connect = function(){
    return 'connect';
}

MySqlAPIClass.prototype.disconnect = function(id){
    return 'disconnect';
}

// 각 구현 클래스들이 인터페이스를 충실히 구현했는지 검증한다.
console.log(Interface.ensureImplement(new MySqlAPIClass(), DBInterface));
console.log(Interface.ensureImplement(new OracleAPIClass(), DBInterface));
console.log(Interface.ensureImplement(new MySqlAPIClass(), DBInterface));