2010-07-05 22 views
12

Sự hiểu biết của tôi là thuật ngữ "referential transparency" chỉ có thể được áp dụng cho mã chức năng. Tuy nhiên, một lời gọi phương thức trên một đối tượng trong mã hướng đối tượng có thể có một thuộc tính tương tự, đó là giá trị trả về của phương thức và trạng thái của đối tượng sau khi gọi phương thức chỉ phụ thuộc vào trạng thái của đối tượng trước cuộc gọi và đối số của phương thức.Điều gì để gọi tương đương với "tính minh bạch tham chiếu" của OOP?

ví dụ: chức năng tham chiếu minh bạch:

i = foo(n, m); 
// return value depends only on n, m 

OO "tham chiếu minh bạch":

i = obj.foo(n, m); 
// return value, and subsequent state of obj, depends 
// only on initial state of obj, n, m 

Có một tên cho khách sạn này?

Nếu tình trạng obj không thay đổi trong suốt cuộc gọi đến foo(), sau đó là "hướng đối tượng" phong cách tương đương với dạng hàm nếu function overloading được hỗ trợ kể từ khi nó có thể được viết lại như sau:

i = foo(obj, n, m); 
// return value depends only on obj, n, m 

Tuy nhiên , là khá phổ biến cho trạng thái của obj để thay đổi trong một cuộc gọi phương pháp, vì vậy tôi không chắc chắn nếu điều này giúp phân tích ...

Trả lời

16

Sai lầm của bạn nghĩ rằng FP và OO bằng cách nào đó khác biệt về cơ bản. "Phiên bản OO" của tính minh bạch tham chiếu chỉ là tính minh bạch tham chiếu.

Biểu thức e là tham chiếu trong suốt nếu và chỉ khi e có thể được thay thế bằng kết quả được đánh giá mà không ảnh hưởng đến hành vi của chương trình.

Vì vậy, nếu bạn có biểu thức o.foo(a), thì nó có tính minh bạch liên quan nếu bạn có thể sửa đổi mã của mình để thay thế mã đó bằng kết quả cuộc gọi mà không thay đổi cách chương trình của bạn hoạt động. Rõ ràng, nếu o.foo bị vô hiệu, bạn không thể làm điều đó. Ditto nếu nó sửa đổi trạng thái bên trong của o. Vì vậy, cách duy nhất để o.foo(a) trở nên minh bạch là nếu kết quả của nó là là một chức năng củaoa.

Trong tâm trí của tôi, "mã chức năng", đồng nghĩa với "mã minh bạch tham chiếu".

+3

Ngoài ra, nếu a) chương trình của bạn phụ thuộc vào nhận dạng đối tượng của kết quả của 'o.foo (a) ', hoặc b)' o.foo (a) 'có một số tác dụng phụ như I/O, bạn không thể thay thế cuộc gọi. – retronym

+0

Tôi cho rằng thật công bằng khi nói rằng tính minh bạch tham chiếu hoàn toàn có thể thực hiện được với mã OO. (Câu trả lời chuẩn có thể có thuộc tính này.) Nhưng câu hỏi chính của tôi là liệu có một tên cho thuộc tính yếu hơn nhưng vẫn hữu ích sau khi gọi phương thức, giá trị trả về và trạng thái cuối cùng của 'o' chỉ phụ thuộc vào trạng thái ban đầu của 'o' và đối số của phương thức. – mjs

+0

Getters tiêu chuẩn được nhấn mạnh ** không ** liên tục minh bạch. Tính minh bạch tham chiếu có nghĩa là kết quả của bạn phụ thuộc vào các tham số được truyền vào ** chỉ **. Một getter ** có ** không có tham số pass-in (trừ khi bạn muốn bắt đầu nói về các tham số ngụ ý như 'this' /' self' trong trường hợp bạn đang thiếu điểm "trong suốt") và giá trị trả về của chúng phụ thuộc vào trạng thái của đối tượng liên quan trong cuộc gọi, một thực thể bên ngoài chức năng. Tính minh bạch tham chiếu là, về cơ bản, "bạn có được những gì bạn thấy và không có gì nhiều hơn". Nếu có những phần không nhìn thấy, thì nó không minh bạch. –

2

trạng thái của đối tượng sau khi gọi phương thức chỉ phụ thuộc vào trạng thái của ob ject trước cuộc gọi và đối số của phương thức.

Tôi giả sử bạn có thể nói rằng phương pháp không có phụ thuộc bên ngoài.

Không giống như tính minh bạch tham chiếu tuy nhiên, tôi không chắc điều này sẽ giúp bạn đạt được điều gì. Tôi cho rằng nó có nghĩa là phương pháp dễ dàng kiểm tra.

+0

Có, tôi đã suy nghĩ về cách tài sản này giúp kiểm tra, và cũng như thế nào nó giúp một lý do về mã. – mjs

+0

Không chắc chắn rằng tôi đồng ý với câu lệnh cuối cùng - nếu một trong các phụ thuộc là trạng thái khởi đầu của đối tượng thì rất khó kiểm tra vì liệt kê tất cả các trạng thái có thể cho bất kỳ đối tượng không tầm thường nào. Tôi đồng ý rằng có phụ thuộc bên ngoài làm cho không gian đầu vào lớn hơn, đến mức bùng nổ tổ hợp) – Paolo

+0

@Paolo đã đồng ý. Tuy nhiên, bạn sẽ đồng ý nó ít nhất là về nguyên tắc ở tất cả các testable, không giống như nói một phương thức gọi 'DateTime.Now' – AakashM

4

Cụm từ chức năng sẽ là tính minh bạch tham chiếu như bạn nói. Tôi sẽ khiêm tốn đề xuất rằng biểu mẫu bạn đã mô tả ở đây với các kết quả tùy thuộc vào các đối số của phương thức cộng với trạng thái của đối tượng được gọi là độ mờ tham chiếu.

4

Tôi không nghĩ rằng thuộc tính bạn mô tả trong kịch bản OO cho bạn bất kỳ điều gì tương tự như những gì tính minh bạch tham chiếu hoạt động trong lập trình hàm. Bạn mô tả một tài sản mà các phương pháp foo đổi chỉ trạng thái của đối tượng obj trong cuộc gọi sau đây:

i = obj.foo(n, m); 

Tuy nhiên, nếu bạn có một đối tượng tham chiếu obj sau đó cuộc gọi đến foo cũng sẽ thay đổi hành vi của người khác vật. Vì các tham chiếu giữa các đối tượng là cần thiết trong OO (có nghĩa là đây là vấn đề bạn không thể dễ dàng tránh được), điều này có nghĩa là thuộc tính mà bạn mô tả không cho bạn biết nhiều về mã. Ví dụ:

a = new Other(obj); 
i = obj.foo(n, m); // changes state of 'obj' and 'a' 

Nếu foo phương pháp là referentially minh bạch (không sửa đổi bất kỳ nhà nước - vừa trở về một số kết quả), thì đó sẽ là một tài sản hấp dẫn - bởi vì nó sẽ không thay đổi trạng thái của a.

+0

Tôi đánh giá cao quan điểm của bạn rằng nếu trạng thái của obj thay đổi, thì về mặt lý thuyết bất cứ điều gì có thể xảy ra khi foo() được gọi vì obj có thể có các kết nối tới bất kỳ đối tượng nào khác trong hệ thống, và tôi không xem xét điều này khi đặt câu hỏi. Tuy nhiên, tôi nghĩ OOP "tính minh bạch tham chiếu" vẫn là một khái niệm có ý nghĩa và hữu ích nếu các thay đổi đối với obj bị hạn chế đối với các kiểu nguyên thủy hoặc vô hướng của nó. Tài sản này làm cho nó dễ dàng hơn để kiểm tra và lý do về mã, ví dụ. – mjs

+1

"sau đó về mặt lý thuyết bất cứ điều gì có thể xảy ra khi foo()" chạm vào móng trên đầu. Vì điều này là đúng, nó trở nên khó khăn hơn nhiều để chắc chắn về hành vi của một chương trình bao gồm một cuộc gọi đến foo(). Trên thực tế, các lập trình viên phải làm nhiều công việc hơn để đảm bảo tính mô-đun và sự an toàn của một đối tượng như vậy. Hơn nữa, nó thường là một mối quan tâm toàn cầu: Bạn phải tiền tố chắc chắn của bạn với "Giả sử lớp được sử dụng như dự định ..." – MtnViewMark

Các vấn đề liên quan