Kết hợp getters và setters


16

Các thư viện JavaScript như jQuery, kết hợp 'getters' và 'setters' trong giao diện lập trình chẳng hạn:

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

sẽ đặt màu hoặc

 $('element').css();

sẽ nhận được css cho một phần tử.

Có một tên cho một mẫu như vậy và nó có phải là một thực hành tốt để sử dụng trong các ứng dụng?

Câu trả lời:


12

Martin Fowler gần đây đã đặt tên cho nó là getter và setter quá tải trong bài viết này :

Gần đây tôi đã tìm hiểu về Javascript và một điều gây ấn tượng với tôi là thói quen sử dụng cùng tên hàm cho getter và setter. Vì vậy, nếu bạn muốn tìm hiểu chiều cao của banner trong jQuery bạn sẽ sử dụng $("#banner").height()và nếu bạn muốn thay đổi chiều cao bạn sẽ sử dụng $("#banner").height(100).

Quy ước này quen thuộc với tôi, vì nó được sử dụng bởi Smalltalk. Bạn có thể nhận được một giá trị với banner heightvà thay đổi nó với banner height: 100. Biết rằng đó là một quy ước smalltalk là đủ để tôi mong đợi nó, vì tôi có một tình yêu xa vời nhưng tuân theo ngôn ngữ đó. Nhưng ngay cả những điều tốt nhất cũng có sai sót, và tôi không thể che giấu sự không thích của mình đối với phong cách mã hóa này ...

Mặc dù có sở thích này, bạn vẫn phải tuân theo các quy ước về ngôn ngữ mà bạn đang làm việc. Nếu tôi viết lại Smalltalk, tôi vẫn sẽ sử dụng height:100để duy trì tính nhất quán với các quy ước của ngôn ngữ. Tuy nhiên, Javascript không được chú ý vì có các quy ước mạnh mẽ, vì vậy ở đây tôi muốn tránh quy ước này, ngay cả khi nó được sử dụng bởi jQuery ...


1
Mặc dù tôi thường đồng ý với hầu hết những gì Fowler nói, tôi không đồng ý với việc anh ấy không thích điều này. Lý do của ông là JavaScript không có các quy ước mạnh như Smalltalk, khiến nó có thể sử dụng được ở đó. Tuy nhiên, jQuery có các quy ước mạnh mẽ và JavaScript không phải là jQuery. jQuery là một khung công tác.
CaffGeek

@Chad, tôi phải không đồng ý với cách đọc của bạn về điều đó. Lập luận của ông là nó thiếu tính minh chứng và tính nhất quán. Anh ấy nói rằng anh ấy sử dụng nó trong Smalltalk vì sự nhất quán với những mối quan tâm khác của anh ấy. Anh ta không tranh luận rằng các quy ước của Smalltalk bằng cách nào đó giảm thiểu hoặc loại bỏ vấn đề.
Winston Ewert

2

Nó được gọi là "nạp chồng phương thức" trong các ngôn ngữ OO hoặc "nạp chồng hàm" trong các ngôn ngữ không phải OO.

Có hay không thực hành tốt là một chủ đề của cuộc tranh luận gần như nhiều getters / setters so với các thành viên công cộng. Những người ở phe chuyên nghiệp và phe đối lập có thể cắt răng của họ bằng các ngôn ngữ có tính năng này hoặc không và được đặt theo cách của họ. Tôi sử dụng nó và thích thực hành vì một số lý do:

  • Bối cảnh trong đó nó được sử dụng khá tốt tách biệt cái này với cái khác.
  • Chuẩn bị gethoặc setcho tên phương thức thêm tính dài dòng.
  • Nếu có nhiều getters (ví dụ: một cho intvà một cho double), việc thay đổi loại trong LHS của một bài tập ( int x = foo.bar()so với double x = foo.bar()) không yêu cầu thay đổi mã ( barAsInteger()so với barAsDouble()) sang bên phải nếu lớp cung cấp cả hai. Mặt trái của vấn đề này là đôi khi có thể khó biết chính xác phương thức nào đang được gọi chỉ bằng cách xem mã.

Nó cũng được gọi là "nạp chồng" trong C ++.
DeadMG

Cả hai thuật ngữ đều áp dụng cho C ++ vì nó có cả phương thức và chức năng trần trụi.
Blrfl

1

Vì JavaScript không có các thuộc tính thực tế (trong đó việc thiết lập một giá trị thực sự có thể thực thi mã), nên patter là một trong đó thực hiện thành ngữ thuộc tính. (Ngay cả khi bạn gọi nó là cái gì khác.)

Vì vậy, trong các ngôn ngữ triển khai các thuộc tính thực, bạn sẽ làm điều này thay vào đó:

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

Nếu bạn sử dụng mẫu JavaScript trong ngôn ngữ xử lý các thuộc tính, bạn sẽ làm điều gì đó bất thường. Đó có thể sẽ không phải là một ý tưởng tốt. Xử lý các thuộc tính theo cách ngôn ngữ có nghĩa là xử lý chúng, vì vậy bạn không nhầm lẫn những người khác làm việc với bạn.


"Nơi thiết lập một giá trị thực sự có thể thực thi mã". Điều này thực sự không còn đúng nữa. Đó là một phần của thông số kỹ thuật kể từ ECMA 5
Demian Brecht

@Dppy: Nhưng, JQuery hoạt động trong các trình duyệt không triển khai ECMA 5.
John Fisher

Tôi đã không đề cập bất cứ điều gì về khả năng tương thích giữa các trình duyệt, chỉ là trích dẫn không chính xác như được viết.
Demian Brecht

@Dppy: Văn bản "JavaScript không có thuộc tính thực tế" là chính xác nếu bạn cho rằng nó sử dụng các phiên bản JavaScript phổ biến nhất hiện có. Vì chúng ta đang thảo luận trong bối cảnh triển khai JQuery, nên câu lệnh sẽ đúng. Tuy nhiên, cảm ơn bạn đã chỉ ra rằng các phiên bản JavaScript mới hơn có các thuộc tính thực sự.
John Fisher

0

Tôi nghĩ bạn đang tìm kiếm properties


Đó là tên của chức năng được cung cấp trong C # (và có lẽ các ngôn ngữ .NET khác?) Tương tự như vậy, nhưng nó không thực sự giống như vậy.
Thomas Owens

Wikipedia đồng ý mặc dù: en.wikipedia.org/wiki/Property_(programming)
thekip

Cảm ơn, không thực sự bạn có thể có tiếng nói trường hợp bạn thiết lập hoặc nhận được một mức lương người trong một ứng dụng person.salary('10000')hoặc person.salary()hoặc tương đương.
yannis

1
Tôi không thấy thế nào. "Các thuộc tính được đọc và viết như các trường", điều này không đúng trong ví dụ trong bài viết gốc. Ở đó, các cuộc gọi phương thức rõ ràng được thực hiện. Nó rất giống nhau, nhưng không hoàn toàn giống nhau.
Thomas Owens

1
@yannis Điều này không đúng. JavaScript có một cú pháp cho các thuộc tính và nó không phải là những gì bạn mô tả trong câu hỏi ban đầu. Xem en.wikipedia.org/wiki/Property_(programming)#JavaScript để biết cách triển khai và sử dụng các thuộc tính trong JavaScript.
Thomas Owens

0

Tôi hoàn toàn chống lại điều đó vì một lý do đơn giản: Một Lớp, Phương thức hoặc Hàm chỉ nên làm một việc - theo ý kiến ​​của tôi, và kết hợp phương thức gettersetterphương thức sẽ vi phạm quy tắc đó. Kết quả là:

  1. Các returngiá trị của hàm khác nhau dựa trên nếu getter hoặc setter khối được thực thi. Điều này chỉ đơn giản có thể dẫn bạn vào một cơn ác mộng bảo trì. Phương pháp của bạn nên quay lại chỉ có một kiểu dữ liệu / đối tượng trong mọi trường hợp - hoặc trả lại null, falsehoặc ném một exceptiontrong trường hợp lỗi.
  2. Kiểm tra đơn vị viết sẽ khó hơn vì chức năng chịu trách nhiệm cho hai chức năng hoàn toàn khác nhau.
  3. Viết tài liệu cho một phương pháp hoặc chức năng như vậy là khó khăn hơn vì lý do rõ ràng.
  4. Sẽ không nhất quán khi cần nhiều phương thức getter - như đã được đề cập trong Blrflcâu trả lời.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.