组合获取器和设置器


16

诸如jQuery之类的JavaScript库在编程界面中结合了“ getters”和“ setters”,例如:

 $('element').css({'color','blue'});

将设置颜色或

 $('element').css();

将获取元素的css。

这种模式有名称吗,在应用程序中使用是一种好习惯吗?

Answers:


12

Martin Fowler最近在本文中将其命名为Overloaded getter and setter :

最近,我一直在使用Javascript,而令我感到惊讶的是,习惯对getter和setter使用相同的函数名。因此,如果要在jQuery中查找横幅的高度,则可以使用$("#banner").height(),如果要更改高度,则可以使用$("#banner").height(100)

我对这个约定很熟悉,因为它是Smalltalk所使用的。您可能会得到一个值,banner height并使用进行更改banner height: 100。知道这是一次小谈话惯例足以让我喜欢它,因为我对这门语言有着遥远而持久的爱。但是即使是最好的东西也有缺陷,对于这种编码风格,我无法掩饰自己的不喜欢...

尽管有这种偏好,您仍然必须遵循所使用语言的约定。如果我再次写Smalltalk,我仍然会使用它height:100来保持与语言约定的一致性。但是,Javascript并没有因为它具有强的约定而闻名,因此在这里我宁愿避免使用该约定,即使jQuery使用它也是如此。


1
尽管我通常都同意福勒的大部分意见,但我不同意他对此的不满。他的理由是JavaScript没有像Smalltalk这样的强约定,这使它在那里可用。但是,jQuery确实有很强的约定,而JavaScript不是jQuery。jQuery是一个框架。
CaffGeek

@乍得,我不同意您的阅读。他的论点是缺乏明确性和一致性。他说他在Smalltalk中使用了它,因为与其他对象的一致性胜过了他的担忧。他并不是在说Smalltalk的约定以某种方式缓解或消除了这个问题。
Winston Ewert

2

在OO语言中称为“方法重载”,在非OO语言中称为“函数重载”。

无论是好的做法还是好礼,还是公众成员,这是否是一个好习惯一直是争论的话题。赞成和反对方面的人可能会切磋那些具有此功能或没有此功能且以自己的方式设置的语言。我使用它并且喜欢这种做法,原因有很多:

  • 它被很好地使用的上下文将一个彼此分开。
  • 预先考虑getset方法名加上冗长。
  • 如果有多个吸气剂(例如,一个用于int和一个用于double),改变在分配(的LHS类型int x = foo.bar()double x = foo.bar())不需要代码变化(barAsInteger()相对于barAsDouble()如果类既提供)到右侧。不利的一面是,有时仅通过查看代码就可能很难准确地知道正在调用哪个方法。

在C ++中,它也称为“函数重载”。
DeadMG 2011年

这两个术语都适用于C ++,因为它同时具有方法和裸函数。
Blrfl 2011年

1

由于JavaScript没有实际属性(在其中设置值可以实际执行代码),因此模式是一种实现属性惯用语的模式。(即使您称之为其他名称。)

因此,在实现实物属性的语言中,您应改为:

element.css = ...
x = element.css

如果您要使用处理属性的语言使用JavaScript模式,那么您将做一些不正常的事情。 那可能不是一个好主意。 使用语言处理属性的方式来处理属性,因此您不会混淆与您一起工作的其他人。


“在其中设置值可以实际执行代码的地方”。这实际上不再是真的。自ECMA 5
Demian Brecht

@Demian:但是,jQuery的原理是在浏览器中没有实现ECMA 5
约翰·费希尔

我没有提到有关跨浏览器兼容性的任何内容,只是引用的文字不正确。
Demian Brecht

@Demian:如果您假定文本使用的是最常用的JavaScript版本,则文本“ JavaScript没有实际属性”是正确的。由于我们在JQuery实现的上下文中进行讨论,因此该语句是正确的。感谢您指出,较新版本的JavaScript具有真正的属性。
约翰·费舍尔

0

我想你在找 properties


这就是C#(也许还有其他.NET语言?)中提供的功能的名称,与之类似,但这并不是一回事。
托马斯·欧文斯

维基百科对此表示同意:en.wikipedia.org/wiki/Property_
编程

谢谢你,不是真的,你可能有你设置的情况下,发言权或在应用程序中获得一个人的工资person.salary('10000')person.salary()或相似。
yannis 2011年

1
我不知道如何。“属性的读取和写入就像字段一样”,这在原始帖子的示例中是不正确的。在那里,进行显式方法调用。这非常相似,但不完全相同。
汤玛斯·欧文斯

1
@yannis这是不正确的。JavaScript具有属性的语法,而这根本不是您在原始问题中所描述的。有关如何在JavaScript中实现和使用属性的信息,请参见en.wikipedia.org/wiki/Property_(programming)#JavaScript
Thomas Owens

0

我完全反对这一点,原因很简单:类,方法或函数应该只做一件事-在我看来,将gettersetter方法结合起来将违反该规则。作为结果:

  1. return函数的值根据是否执行gettersetter块而有所不同。这可能会使您陷入可维护性的噩梦。在任何情况下null,您的方法都应仅返回一种类型的数据/对象-或return ,falseexception在出现错误的情况下引发。
  2. 编写单元测试会更加困难,因为该功能负责两种完全不同的功能。
  3. 由于明显的原因,为这种方法或函数编写文档更加困难。
  4. 当需要多种吸气剂方法时,这将是不一致的-正如在Blrfl答案中已经提到的。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.