Làm thế nào để cải thiện năng suất với các giao diện ngầm ẩn của Wap và làm thế nào để so sánh với khái niệm về Phương thức mở rộng của C #?


21

Trong Hướng dẫn ngôn ngữ Go, họ giải thích cách các giao diện hoạt động:

Đi không có lớp. Tuy nhiên, bạn có thể định nghĩa các phương thức trên các kiểu cấu trúc. Trình nhận phương thức xuất hiện trong danh sách đối số riêng giữa từ khóa func và tên phương thức.

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

Một loại giao diện được xác định bởi một tập hợp các phương thức. Một giá trị của loại giao diện có thể chứa bất kỳ giá trị nào thực hiện các phương thức đó.

Đây là cách duy nhất để tạo giao diện trong Go. Google giải thích thêm rằng:

Một kiểu thực hiện một giao diện bằng cách thực hiện các phương thức. Không có tuyên bố rõ ràng về ý định [tức là interfacetuyên bố].

Các giao diện ngầm định tách các gói triển khai khỏi các gói xác định các giao diện: không phụ thuộc vào các giao diện khác.

Nó cũng khuyến khích định nghĩa về các giao diện chính xác, bởi vì bạn không phải tìm mọi cách triển khai và gắn thẻ nó với tên giao diện mới.

Tất cả điều này nghe có vẻ đáng ngờ giống như Phương thức mở rộng trong C # , ngoại trừ các phương thức trong Go là đa hình một cách tàn nhẫn; họ sẽ hoạt động trên bất kỳ loại nào thực hiện chúng.

Google tuyên bố rằng điều này khuyến khích sự phát triển nhanh chóng, nhưng tại sao? Bạn có từ bỏ một cái gì đó bằng cách di chuyển khỏi các giao diện rõ ràng trong C #? Các phương thức mở rộng trong C # có thể cho phép một người rút ra một số lợi ích mà giao diện Go có trong C # không?



1
Các giao diện Go này nghe giống như những gì các mẫu C ++ có thể làm hơn các phương thức mở rộng C #. Trong C # không có gì giống như bất kỳ loại nào thực hiện các phương thức A và B, nhưng bạn có thể làm điều đó bằng cách sử dụng các mẫu C ++.
Svick


Không phải 'giao diện ngầm' chỉ là một hình thức gõ vịt?
Allon Guralnek

"Không phải 'giao diện ngầm' chỉ là một hình thức gõ vịt sao?" Giao diện của Go là một ví dụ về cách gõ cấu trúc. Khái niệm rất giống nhau.
mortdeus

Câu trả lời:


12

Tôi không thấy các phương thức mở rộng và giao diện ngầm hoàn toàn giống nhau.

Trước tiên hãy nói về mục đích.

Các phương thức mở rộng tồn tại dưới dạng đường cú pháp đặc biệt để cung cấp cho bạn khả năng sử dụng một phương thức như thể nó là thành viên của một đối tượng, mà không có quyền truy cập vào bên trong của đối tượng đó. Nếu không có các phương thức mở rộng, bạn có thể thực hiện chính xác điều tương tự, bạn sẽ không nhận được cú pháp dễ chịu someObjectYouCantChange.YourMethod()và thay vào đó phải gọi YourMethod(someObjectYouCantChange).

Tuy nhiên, mục đích của các giao diện ngầm là để bạn có thể thực hiện giao diện trên một đối tượng mà bạn không có quyền truy cập để thay đổi. Điều này cung cấp cho bạn khả năng tạo mối quan hệ đa hình giữa bất kỳ đối tượng nào bạn tự viết và bất kỳ đối tượng nào bạn không có quyền truy cập vào bên trong.

Bây giờ hãy nói về hậu quả.

Các phương thức mở rộng thực sự không có, điều này hoàn toàn phù hợp với các ràng buộc bảo mật tàn nhẫn mà .NET cố gắng sử dụng để hỗ trợ các quan điểm khác biệt về một mô hình (phối cảnh từ bên trong, bên ngoài, người thừa kế và người hàng xóm). Hậu quả chỉ là một số cú pháp dễ chịu.

Hậu quả của giao diện ngầm là một vài điều.

  • Việc thực hiện giao diện ngẫu nhiên, đây có thể là một tai nạn hạnh phúc hoặc vi phạm LSP tình cờ bằng cách gặp giao diện của người khác mà bạn không có ý định trong khi không tôn trọng ý định của hợp đồng.
  • Khả năng dễ dàng làm cho bất kỳ phương thức nào chấp nhận một mô hình của bất kỳ đối tượng cụ thể nào bằng cách đơn giản phản chiếu giao diện đối tượng đó (hoặc thậm chí chỉ tạo một giao diện đáp ứng các yêu cầu phương thức đó và không hơn).
  • Khả năng tạo bộ điều hợp hoặc các mẫu tương tự khác dễ dàng hơn đối với các đối tượng bạn không thể can thiệp vào các bộ phận bên trong.
  • Trì hoãn thực hiện giao diện và triển khai nó sau mà không cần phải chạm vào triển khai thực tế, chỉ thực hiện nó khi bạn thực sự muốn tạo một người triển khai khác.

Tiện ích của các phương thức mở rộng trong Linq có được phần lớn nhờ khả năng ghép một triển khai phương thức lên một giao diện, đặc biệt IEnumerableIQueryable. Mặc dù bạn có thể giả mạo điều này với staticcác phương thức trong một lớp tiện ích, nhưng nó sẽ vụng về.
Robert Harvey

@RobertHarvey Không nhất thiết phải chính xác khi tuyên bố nó đặt phương thức trên một giao diện, lưu ý sự khác biệt giữa một phương thức thực tế trên một giao diện và một phương thức mở rộng: Một phương thức trên một giao diện sẽ được triển khai bên trong lớp thực hiện giao diện đó, và do đó có sẵn quyền truy cập vào rất nhiều hơn bất kỳ phương pháp mở rộng nào. Một lần nữa, đó là một sự thay đổi về phối cảnh, mã được triển khai bên trong một lớp được đưa ra một phối cảnh đặc biệt so với bên ngoài.
Jimmy Hoffa
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.