-1

编辑:删除了更高层次的想法,包括特定问题和不易迁移的代码。

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

从继承 POV,我想要类似的东西:

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

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

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财产不被无意改变。

4

2 回答 2

1

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() {…};
于 2013-10-09T23:44:20.040 回答
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 代码都看不到变量 mileage。就像一个私有的 java/C++ 类变量。但是,我会考虑您是否需要这种保护。我经常使用模块,但不适用于 java/C++ 中的类实例等小对象。

于 2013-10-09T22:12:32.623 回答