处理API设计和面向对象语法糖

6

简介阅读:

按照上述模式,我创建如下的库/API:

var Proto = {
  constructor: function () {
    this.works = true;
  },
  method: function () {
    return this.works;
  }
};

现在,对于需要与我的原型进行交互的库用户(原型不提供工厂函数),他们必须实例化并初始化对象。
// instantiate
var p = Object.create(Proto);
// initialize
p.constructor();

这是一种不友好且啰嗦的方式,强制用户实例化和初始化我的对象。
个人而言,因为我在所有应用程序中使用 pd ,所以我有以下简化语法糖。
// instantiate or initialize
var p = Proto.new();
// or without bolting onto Object.prototype
var p = pd.new(Proto);

然而,我认为强制用户使用pd并不好,因此我不确定使我的库可用的最佳方法是什么。
  1. 人们创建Proto的新实例并自己调用.constructor
  2. 强制人们使用pd
  3. 提供.create样式的工厂函数
  4. 放弃并使用new 和.prototype

已经提到了1和2。

3基本上就是提供.create样式的工厂函数。

Proto.create = pd.new.bind(pd, Proto);

4会让我感到悲伤,但是遵循已知的标准做事方式可以提高可用性。

通常,当使用非标准OO模式时,最容易让人们在其应用程序中使用我的库的机制是什么?

我目前的倾向是

// here is my Prototype
Proto;
// here is how you instantiate a new instance
var p = Object.create(Proto);
// here is how you initialize it
// yes instantiation and initialization are seperate and should be.
p.constructor();
// Want sugar, use pd.new
2个回答

2

现在,如果您使用一个小型API来帮助您构建传统的构造函数,使用几乎像原型作为类一样的语法,那么您很可能会让您的库客户更容易使用。 API示例用法:

// Superclass
var Person = Class.extend({
    constructor: function (name) {
        this.name = name;
    },
    describe: function() {
        return "Person called "+this.name;
    }
});

// Subclass
var Worker = Person.extend({
    constructor: function (name, title) {
        Worker.super.constructor.call(this, name);
        this.title = title;
    },
    describe: function () {
        return Worker.super.describe.call(this)+" ("+this.title+")";
    }
});
var jane = new Worker("Jane", "CTO");

实现方式:


但这基本上就是第四点。我正在创建作为函数的对象。我真的不想这样做。 - Raynos
@Raynos:没错,但这是其他人都在做的事情。我更希望每个人都使用原型作为类(PACs),但这可能永远不会发生。然而,类字面量很可能会进入ES6,然后一切看起来都像PACs。我认为这是可以接受的,因为它保持了兼容性。底层结构非常清晰。我只是不想去管理它。如果ES6能够为我做到这一点-那就好。 - Axel Rauschmayer
我选择了"这是如何实例化和初始化PAC的方法。现在你知道了,你可以使用我的代码,一切都很清晰明了。 - Raynos

0

我认为提供new(Prototype, [arguments])函数是一个不错的选择,可以通过"use pd"选项来实现。从依赖性的角度来看,这甚至不会太糟糕(因为您可以将此函数单独打包,并且只有几行代码)。

提供特殊函数也符合历史观点。如果您回到Smalltalk甚至更近期的Python,您会发现对象创建(new)和初始化(init,构造函数)有单独的函数,我们没有注意到这种分离的唯一原因是它们为对象实例化提供了语法糖。


这个 .new 函数应该添加到我创建的每个 Prototype "类"中,还是仅仅加到 Object.prototype.new 上(让糟糕的程序员去死吧!)。基本上将 .new 添加到所有我的“类”上会破坏拥有 Object.prototype.new 的意义。 - Raynos
你可以遵循古老的传统,将框架函数放在一个主父类中(强制所有类都继承自它),或者你可以创建一个简单的非方法函数,比如pd.new。 - hugomg
等等,"主父类" "强制继承"。 - Raynos
大多数面向对象语言都有一个Object类,要求所有人都必须继承。你可以使用现有的sugar通过bolt things to Object.prototype,也可以用自己的方式(通过新的Object子类和其他无需现有sugar的方法)。我的原始观点只是大多数面向对象语言到目前为止都采用了大量的语法糖来使事情看起来简单,因此在没有语法糖的情况下使用轻量级库来完成任务实际上并不那么糟糕。 - hugomg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接