Node.js:如何继承'来自抽象类?

时间:2016-02-10 15:49:44

标签: node.js oop

我正在使用node.js(+ angular等)构建一个Web应用程序 应用程序必须从不同的提供程序中检索一些数据(类似于目录项列表),这些数据以不同的方式公开它们的数据。

在该模块中,我将为所有提供者提供一些共同的功能,以及一些对其中任何提供者都独有的功能。

我当前(糟糕)的实现是这样的:

var providers = [
  {  name: 'Apple', /* ... */ },
  {  name: 'Samsung', /* ... */ },
  {  name: 'Google', /* ... */ },
];

exports.syncCatalogues = function(search, callback) {
  var allItems = [];
  for (var p = 0; p < providers.length; p++) {
    exports.getCatalog(providers[p], function(err, catalog) {
      if (err) {
        return callback(err);
      }
      exports.getItems(providers[p], catalog, function(err, items) {
        if (err) {
          return callback(err);
        }
        allItems = allItems.concat(items);
        callback(null);
      });
    });
  }
};

我的getCatalog()和getItems()实现就像这样丑陋:

exports.getCatalog(provider, callback) {
  if (provider.name === 'Apple') {
    // code for Apple provider ...
  }
  // and so on ...
};


exports.getItems(provider, callback) {
  if (provider.name === 'Apple') {
    // code for Apple catalog ...
  }
  // and so on ...
};

我知道ES5(我坚持认为)抽象类并不容易实现,但我确信有一种比这更好的方法(代码更易读,可维护,可测试)。 。: - (

3 个答案:

答案 0 :(得分:2)

我的回答是一种可能的替代解决方案。

我个人不喜欢原生的javascript对象mecanics。所以我通常使用像Mootools这样的库来制作干净的物体。

Mootools文档中的示例:

Display display = ((Activity)ctx).getWindowManager().getDefaultDisplay();
            Point size = new Point();
            display.getSize(size);
            //int width = size.x;
            int height = size.y;

            ((MyRecyclerHolder) holder).outer.getLayoutParams().height = height/3;(or whatever ratio you want)

查看在线文档:http://mootools.net/

答案 1 :(得分:2)

有许多方法可以在JavaScript中实现继承。 这是一个,我认为最简单,因为你只使用普通对象操作并使用原型继承。

您可以使用原型对象来放置公共代码,而不是基类。 然后根据原型创建一个对象并向其添加特定代码。

var providerPrototype = {
  name: 'Prototype',
  alertName: function() {  // this is common function, all objects
    alert(this.name);      // will have it
  }
};

var appleProvider = Object.create(providerPrototype);
appleProvider.name = 'Apple';
// this is a specific function for 'Apple'
appleProvider.getCatalog = function(callback) {
  return callback(null, ['iPhone', 'Mac Mini']);
}
appleProvider.alertName = function() {
   // call 'base' method
   providerPrototype.alertName.call(this);
   alert('All rights reserved.');
}

var samsungProvider = Object.create(providerPrototype);
samsungProvider.name = 'Samsung';
// this is a specific function for 'Samsung'
samsungProvider.getCatalog = function(callback) {
  return callback(null, ['Galaxy S3', 'Galaxy S4']);
}

var providers = [
  appleProvider, samsungProvider
];

var syncCatalogues = function(search, callback) {
  var allItems = [];
  for (var p = 0; p < providers.length; p++) {
    var aProvider = providers[p];
    aProvider.getCatalog(function(err, catalog) {
      if (err) {
        return callback(err);
      }
      aProvider.alertName(); // call the base method
      alert(catalog);
    });
  }
};

syncCatalogues();

另请参阅Mozilla javascript文档中的Inheritance and the prototype chain

这是an example of splitting classes over node.js modules

答案 2 :(得分:2)

我是nodeJS的新手,但我认为下面的代码只有在ES6之后才有可能。我希望能帮助像我这样的新手。如下:

class BaseClass {
    constructor(){
        console.log('Object created INHERITED');
    }

    toCallFromChild(){
        console.log('Called by child');
        this.toOverride();
    }

    toOverride(){} //to override
}

class childClass extends BaseClass{
    toOverride(){
        console.log ('Override by child');
    }
}

var instance = new childClass();
instance.toCallFromChild();