1

这个问题涉及 CoffeeScript,但同样的问题仍然适用于 JavaScript。考虑这个例子:

class Parent    
    func: ->
        alert @member

class Child extends Parent    
    constructor: ->
        @greet()

    greet: ->
        @member = 'hello!'
        @func()

Parent本身是没有用的。(new Parent).func()返回undefined

我的问题是:

  • 定义Parent只为子类提供通用功能和属性的类有什么问题吗?Parent可以是它自己文件中的一个复杂类,为原型链中的类提供功能。如果没有文档,这可能会令人困惑。

  • Child.greet中,我们动态地添加member到一个 Child 对象。向对象添加新成员而不首先在构造函数中初始化它们有什么问题吗?这样做更好constructor: -> @member = null; @greet()吗?这样,下一个程序员就知道对象将拥有哪些成员,并将避免未定义变量的问题。另一方面是代码会有更多的噪音,这是 JavaScript 不需要的。

  • 最后,是否有源代码是 CoffeeScript 中惯用 OOP 的一个很好的例子?

4

2 回答 2

2

关于你的第一个问题,不,我不认为这样做有什么本质上的错误。我会说这是模板方法模式的一种情况(使用属性访问而不是方法,但基本相同)。我确实为您的代码结构增加了一些复杂性,因此,如果可以以更简单的方式解决它,我建议使用更简单的解决方案。

关于不在构造函数中初始化成员变量,理想情况下构造函数应该使对象处于可用状态,这并不一定意味着初始化每个可能的成员变量。对于那个特定的代码片段,@member = null在我看来,添加不会增加任何东西。一个糟糕的构造函数的例子是要求用户在使用它之前做更多的事情而不是实例化对象,例如:

c = new Circle
c.radius = 5 # Need to set the radius to get the area.
console.log c.area() # If i hadn't set the radius this would break.

我不知道惯用的 OO CoffeeScript 的良好来源。我认为 Smooth CoffeeScript 是一本学习这门语言的好书,它有一章是关于 OO的,但如果它足够透彻的话我不会。

于 2012-08-03T18:37:11.583 回答
1

是的,这绝对是模板方法模式的一个案例。对于 Coffeescript 的一些惯用指南,我会查看http://coffeescriptcookbook.com/

但是任何关于惯用 Ruby 的 Ruby 书籍/参考资料肯定也会有所帮助。

于 2012-08-09T15:14:38.470 回答