“组合”的Getter / Setter VS个体方法的优点是什么?


12

这就是我所谓的“组合式” getter / setter方法(来自jQuery):

var foo = $("<div>This is my HTML</div>"),
    myText;

myText = foo.text(); // myHTML now equals "This is my HTML" (Getter)
foo.text("This is a new value"); // The text now equals "This is a new value")

这与单独(理论)方法的逻辑相同:

var foo = $("<div>This is my HTML</div>"),
    myText;

myText = foo.getText(); // myHTML now equals "This is my HTML" (Getter)
foo.setText("This is a new value"); // The text now equals "This is a new value")

我的问题:

在设计类似jQuery的库时,为什么要决定走第一条路线而不走第二条路线?一看,第二种方法难道不是更清晰,更容易理解吗?


6
马丁·福勒(Martin Fowler)并不喜欢他所谓的“超载吸气
塞特机

1
我曾经喜欢get / set拆分方法(认为它使代码更“明显”),但是最近发现重载的getter / setter模式更具吸引力。它可以使代码更整洁。我从来没有发现自己喜欢福勒先生的妥协。在我看来,这是两全其美。
Brian Knoblauch

马丁·福勒(Martin Fowler)唯一反对它的真正论据是当“ getter”传入一个论据时,在这种情况下,它使读者感到困惑,因为它看起来不像是一个getter。到目前为止,我得出的结论是,如果您遵循以下约定:getter不带参数,而setter带一个参数,再加上清晰的API注释,则jQuery / Angular方法应该就可以了。目前。
zumalifeguard 2014年

Answers:


13

纯粹是在这里推测,但是我倾向于相信那些在构造jQuery时使用了大量功能样式的jQuery开发人员显然倾向于功能性范例。

鉴于此,在功能范式中,存在着一种减少冗余的强烈文化,可以说第二种方法具有不必要的冗余。对于习惯于所有常见命令性语言的人来说,第一种方法可能并不明确,但是毫无疑问,只有一种方法而不是两种方法,却可以事半功倍。这可能很危险,但是它是功能范式中的常用工具,并且很快就会被人们习惯。

在功能范例中进行练习,您会很快克服对仪式的渴望,并学会欣赏事半功倍的能力。尽管可以识别这是基于偏好的主观选择,就像许多人对空白管理有偏好一样。这样,我并不是说有一种更好的方法,而是让它们成为人们习惯的东西,这很可能就是jQuery具有它所采用的方法的原因。

这就是为什么我相信jQuery开发人员会这样做的原因,并且通常就是为什么有人会采用这种方法的原因。


2
同意,再加上我希望尽可能减少JS大小。
Matt S

-1表示命令性/详细点和功能/隐含点。

3
@MattFenwick我不是要冒犯,您是在说功能范式倾向于隐性,而命令式范式倾向于显性是不正确的吗?我并不是说任何一个都更好,只是一个可以适应另一个,这会让您自动以相对于另一种的方式来做事(这两种方式均适用)
Jimmy Hoffa

@Jimmy没问题;我的意思是,根据我的经验,我发现隐含性/显式性与FP /命令性正交。

@MattFenwick可能是,但是我要说的是,除了类型推断可以允许很多隐式并且对于HM类型系统是通用的以外,FP语言的其他通用特性也倾向于隐式,以及所有的函数即函数。函数没有明确的名称,只是您需要隐式学习和知道的符号,或者是列表或元组的常规用法,它们需要成员含义和位置的隐式知识,而不是DU(考虑一下writer monad的工作方式)。我也倾向于看到单个字母参数名称的共性,但是您可能是对的
Jimmy Hoffa 2013年

2

表格

foo.text("This is a new value"); 

可以暗示很多事情。最常见的是,它建议一个foo对象,该对象具有一种称为“ text接受字符串” 的方法,可以执行某些操作。完全没有暗示这是一个属性。

在许多语言中,这可以视为的缩写形式。

var result = foo.text("This is a new value"); 

结果被丢弃。因此,这种方法过于模棱两可,无法成为设置属性的有效方法(从代码可读性的角度来看)。


这是一个很好的观点!当我阅读javascript时,我戴上FP护目镜,事情看起来有所不同,所以我什至没有想到这一点,但是如果我在C#中看到这样的代码,我的反应就是你指的是“这种方法在做什么” ??”。
吉米·霍法

1

这有点投机,但这是我的看法。

jQuery完全包含了javascript的功能性质。这就是使其如此出色的原因,但是当它们来自更纯粹的面向对象语言(例如Java)时,可能会让许多开发人员挠头。它似乎违反了所有惯例和良好做法。

功能语言倾向于将重点放在声明性语法上。它倾向于像事实陈述那样阅读而不是像命令那样阅读。例

var eligible = customers.where(c => c.age > 30);

可以理解为“合格客户是30岁以上的客户”。相比之下,命令式语言读起来就像命令序列

for (customer in customers)
    if (customer.age > 30)
        eligible.add(customer)

可以理解为“检查每个客户,如果他们的年龄超过30岁,请将其添加到符合条件的集合中”

添加aa set和一个get操作会使jQuery看起来像一个命令库。您可以构建阅读以下语句的方式

// The element tag have an html of <p>hello</p>
$("#element").html("<p>hello</p>"); 

// content represent the html of the element tag
var content = $("#element").html();


//Imperative style

// Set the element tag to an inner html of <p>hello</p>
$("#element").setHtml("<p>hello</p>");

//Get the html of #element, and put it in the content variable
var content = $("#element").getHtml();

通过将动作动词排除在jQuery API之外,它们使它感觉像是声明性API。它给库带来一致的功能感。这就是为什么我认为他们重载了关键字。


1

它使它的行为更像是property,最近才引入JavaScript,因此尚未得到广泛使用,尤其是在jQuery之类的旨在帮助消除浏览器不兼容性的库中。

如果您曾经看过充满此类属性的类定义,则“ set”和“ get”前缀看起来是多余的,因为添加value参数已经告诉您它是一个setter。 Martin Fowler很好地说明了需要参数的吸气剂,但是即使那样,在此上下文中,附加值参数也清楚地表示设置器,以及设置器很少出现在分配的右侧的事实。而且,在编写代码时,无论如何都必须查看该库的文档。

由于您只要求优点,因此我将不介绍缺点。

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.