Javascript:继承封装变量

时间:2013-10-09 21:43:28

标签: javascript node.js

修改:删除了更高级别的提示,包括特定问题和不易转移的代码。

我使用DAO实现了我的DAL。我的应用程序挂钩到各种数据库(主要是出于遗留原因)。为了促进连接的有效和智能使用,我使用ConnectionBroker单例来管理可能(或可能不)打开的各种连接。然后将此ConnectionBroker注入DAO,在那里他们可以请求控制特定连接对象,请求新连接等。

从遗产POV,我想要像:

AbstractDbConnection
      |-- MongoDbConnection
      |-- MsSqlConnection
      |-- CouchDbConnection
      |-- ...

AbstractDbConnection定义接口,并实现一些基于事件的共享逻辑。

var EventEmitter = require('events').EventEmitter;

module.exports = function AbstractDbConnection(host, port, database, login, ...) {
    // private
    var state = StatesEnum.Closed; // StatesEnum = {Open: 0, Closed: 1, ..}; Object.freeze(StatesEnum);

    // api that must be overwritten
    this.connect = function connect() {throw new ...} 
    this.disconnect = function disconnect() {throw new ...}
    ... <more>
    this.getState = function() { return state; }
}
AbstractDbConnection.prototype.__proto__ = EventEmitter.prototype;

然后我使用特定于驱动程序的代码实现接口:

var mssqldriver = require('mssqldriver'), //fictitious driver
    AbstractDbConnection = require(__dirname + '/blah/AbstractDbConnection');


module.exports = function MsSqlConnection(host, port, database, login, ...) {
    var me = this;
    // implement using driver
    this.connect = function connect() {...} 
    this.disconnect = function disconnect() {...}
    ... <more>
    driverSpecificConnection.on('driverSpecificOpenEvent', function() {
       me.emit('open'); // relay driver-specific events into common events
       state = StatesEnum.Open; // how ??
    }
    ...
}
MsSqlConnection.prototype.__proto__ = new AbstractDbConnection();

但显然我想保护state财产不会无意中发生变化。

2 个答案:

答案 0 :(得分:1)

只需在“abstract”构造函数中监听open事件!

var EventEmitter = require('events').EventEmitter;
module.exports = AbstractDbConnection;
var StatesEnum = module.exports.StatesEnum = Object.freeze({
    Open: 0, Closed: 1, …
});

function AbstractDbConnection(host, port, database, login, …) {
    // private
    var state = StatesEnum.Closed;

    EventEmitter.call(this);

    this.getState = function() { return state; }
    this.on('open', function(e) {
        state = StatesEnum.Open;
    });
}
AbstractDbConnection.prototype = Object.create(EventEmitter.prototype);

// api that must be overwritten
AbstractDbConnection.prototype.connect = function connect() {throw new …};
AbstractDbConnection.prototype.disconnect = function disconnect() {throw new …};

var Mssqldriver = require('mssqldriver'), //fictitious driver
    AbstractDbConnection = require(__dirname + '/blah/AbstractDbConnection');
module.exports = MsSqlConnection;

function MsSqlConnection(host, port, database, login, …) {
    AbstractDbConnection.call(this);

    this.driver = new Mssqldriver(…);
    this.driver.on('driverSpecificOpenEvent', this.emit.bind(this, 'open'));
    …
}
MsSqlConnection.prototype = Object.create(AbstractDbConnection.prototype);
MsSqlConnection.prototype.connect = function connect() {…};
MsSqlConnection.prototype.disconnect = function disconnect() {…};

答案 1 :(得分:0)

您可以使用模块模式执行此操作。

var transport_module = function() {
var mileage = 0; // private
return {
    transport : function(distance) {
    mileage += distance;
    }
  };
}

//use it
var car = transport_module(),
boat = transport_module(),
motorcycle = transport_module();


car.transport(10);
boat.transport(5);
motorcycle.transport(20);

任何其他javascript代码都看不到可变里程数。像私有java / C ++类变量一样。但是,我会考虑你是否需要这种保护。我经常使用模块,但不能用于java / C ++中的类实例之类的小对象。