2010-07-01 27 views
9

Trong dự án tôi đang làm việc trên, tôi đã nhận thấy rằng đối với mỗi lớp thực thể có một giao diện. Dường như động lực ban đầu là chỉ phơi bày giao diện cho các dự án/giải pháp khác.C# - Việc thêm giao diện một cách có hệ thống là một thực hành tốt?

Tôi thấy điều này hoàn toàn vô dụng và tôi không thấy điểm tạo giao diện cho mọi lớp học. Nhân tiện, các lớp đó không có bất kỳ phương thức nào chỉ là các thuộc tính và chúng không thực hiện cùng một giao diện.

Tôi có sai không? Hay đó là một thực hành tốt?

Thx

+2

Bạn có một số ví dụ không? Tôi khuyên bạn nên đọc qua câu trả lời ace này: http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface/384067#384067 –

+0

Nếu chúng là các lớp COM, điều này là bình thường (đọc: loại yêu cầu). –

+0

Có thể trùng lặp của [Thực tiễn tốt nhất là trích xuất một giao diện cho mọi lớp?] (Http://stackoverflow.com/questions/3036749/is-it-the-best-practice-to-extract-an-interface- for-every-class) – DavidRR

Trả lời

6

Có thể có nhiều thiết lập hơn được mô tả ở đây để minh chứng chi phí của giao diện. Nói chung chúng rất hữu ích cho việc tiêm phụ thuộc và tách biệt mối quan tâm, kiểm tra đơn vị và chế nhạo, vv .. Hoàn toàn có thể là chúng không được sử dụng cho mục đích này (hoặc bất kỳ mục đích xây dựng nào khác, thực sự) trong môi trường của bạn .

Mã này được tạo hay được tạo theo cách thủ công? Nếu trước đây, tôi nghi ngờ công cụ tạo ra chúng đang làm như vậy để chuẩn bị cho việc sử dụng như vậy nếu nhà phát triển rất nghiêng. Nếu sau này, có lẽ các nhà thiết kế ban đầu đã có một cái gì đó trong tâm trí?

Đối với "thực tiễn tốt nhất" của riêng tôi, tôi hầu như luôn phát triển theo hướng giao diện. Nó thường là một thực hành tốt để tách ra mối quan tâm từ nhau và sử dụng các giao diện như hợp đồng giữa chúng.

+0

Tôi thích YAGNI hơn, nhưng tôi nghĩ các lý do có thể có của bạn đối với các giao diện trong dự án cụ thể này là tại chỗ. – Marc

+2

Nói chung tôi đồng ý với YAGNI. Là một nhà phát triển doanh nghiệp, trọng tâm của tôi luôn là "tốt cho doanh nghiệp" qua "tốt cho mã". Tất nhiên, doanh nghiệp không phải lúc nào cũng hiểu rằng cả hai thường là một và giống nhau :) – David

7

tôi có xu hướng để tạo ra một giao diện cho hầu hết các lớp chủ yếu là do kiểm tra đơn vị - nếu bạn sử dụng dependency injection và muốn kiểm tra đơn vị một lớp học mà phụ thuộc vào các lớp trong câu hỏi, so với cách giữa các ý kiến để mô phỏng một thể hiện của lớp đang được đề cập đến (sử dụng một trong các khung mocking, ví dụ như Rhino-Mocks). Tuy nhiên, thực tế nó chỉ có thể chỉ cho các giao diện, không thực hiện cụ thể (có, về mặt lý thuyết bạn có thể mô phỏng một lớp cụ thể, nhưng có nhiều hạn chế đau đớn).

4

Tính năng này hữu ích cho các thử nghiệm.

Phương pháp có thể lấy tham số kiểu ISomething và có thể là SqlSomething hoặc XmlSomething, trong đó ISomething là giao diện và SqlSomething và XmlSomething là các lớp thực hiện giao diện, tùy thuộc vào việc bạn đang thực hiện kiểm tra (bạn vượt qua XmlSomething trong trường hợp này) hoặc chạy ứng dụng (SqlSomething).

Ngoài ra, khi xây dựng một dự án chung, có thể hoạt động trên bất kỳ cơ sở dữ liệu nào, nhưng không sử dụng công cụ ORM như LINQ (có thể vì công cụ cơ sở dữ liệu có thể không hỗ trợ LINQ to SQL), bạn xác định giao diện bạn sử dụng trong ứng dụng. Sau đó, các nhà phát triển sẽ thực hiện các giao diện để làm việc với cơ sở dữ liệu, tạo lớp MySQLProductRepository, lớp PostgreSQLProductRepository, cả hai đều kế thừa cùng một giao diện, nhưng có chức năng khác nhau.

Trong mã ứng dụng, bất kỳ phương thức nào có tham số là đối tượng kho lưu trữ của loại IProductRepository, có thể là bất kỳ thứ gì.

1

Nếu những lớp đó chỉ có thuộc tính, thì giao diện sẽ không thêm nhiều giá trị, bởi vì không có hành vi nào đang được trừu tượng hóa.

Giao diện có thể hữu ích cho việc trừu tượng, do đó việc triển khai có thể được mô phỏng trong các bài kiểm tra đơn vị. Nhưng trong một ứng dụng được thiết kế tốt, các thực thể nghiệp vụ/miền phải có rất ít lý do để được chế nhạo. Mặt khác, các dịch vụ kinh doanh/miền là một ứng cử viên tuyệt vời cho giao diện trừu tượng.

Tôi đã tạo giao diện cho các thực thể của mình một lần và không thêm bất kỳ giá trị nào. Nó chỉ làm cho tôi nhận ra thiết kế của tôi đã sai.

1

IMHO có vẻ như việc viết giao diện không có lý do gì là vô nghĩa. Bạn không thể được hoàn toàn đóng cửa minded nhưng nói chung làm những điều mà không phải là ngay lập tức hữu ích có xu hướng tích lũy như là chất thải.

Khái niệm nhanh về giá trị bổ sung của nó hoặc giá trị nhận được sẽ đến với tâm trí.

Điều gì sẽ xảy ra khi bạn xóa chúng? Nếu không có gì thì ... họ ở đó để làm gì?

Như một lưu ý phụ. Giao diện cực kỳ hữu ích cho Rhino Mocks, tiêm phụ thuộc và vân vân ...

5

Hiển thị giao diện công khai có giá trị trong việc tạo kiến ​​trúc theo hướng hành vi, lỏng lẻo.

Tạo giao diện cho mọi lớp - đặc biệt nếu giao diện chỉ hiển thị mọi phương thức công khai mà lớp có trong một giao diện duy nhất - là triển khai không tốt khái niệm và (theo kinh nghiệm của tôi) dẫn đến mã phức tạp hơn và không cải thiện trong kiến ​​trúc.

+0

+1 - Hoàn toàn như vậy. Giao diện là một công cụ. Giống như bất kỳ công cụ nào, chúng có sử dụng tốt và sử dụng không tốt. Và ví dụ này không có vẻ tốt. – GalacticCowboy

+0

Nó không phải là quá xấu nếu giao diện tồn tại trước khi lớp học - nhưng chỉ cần tạo 'IFoo' cho mỗi lớp' Foo' không phải là rất hữu ích. – kyoryu

0

Để kiểm tra đơn vị, đó là giao diện ở mọi nơi hoặc phương pháp ảo ở mọi nơi.

Đôi khi tôi bỏ lỡ Java :)

1

Nó có vẻ là một giao diện là vượt trội so với một lớp cơ sở trừu tượng chủ yếu nếu/khi nó là cần thiết để có một lớp mà thực hiện giao diện nhưng được thừa hưởng từ một số lớp cơ sở khác. Nhiều thừa kế không được phép, nhưng nhiều triển khai giao diện. Báo cáo chính tôi thấy khi sử dụng giao diện hơn là lớp trừu tượng (vượt quá mã nguồn bổ sung cần thiết) là việc thay đổi bất kỳ thứ gì trong giao diện đòi hỏi phải biên dịch lại bất kỳ và tất cả mã sử dụng giao diện đó. Ngược lại, việc thêm thành viên công khai vào một lớp cơ sở thường chỉ yêu cầu biên dịch lại chính lớp cơ sở. (*)

(*) Do cách xử lý mở rộng, thêm thành viên vào một lớp sẽ không "yêu cầu" biên dịch lại mã sử dụng lớp đó, nhưng có thể gây ra mã sử dụng các phương thức mở rộng trên lớp để thay đổi ý nghĩa vào lần sau nó (mã sử dụng phương pháp mở rộng) được biên dịch lại.

1

Không có cách nào để nói cho tương lai và xem bạn có cần chương trình chống lại giao diện không. Nhưng nếu sau này bạn quyết định sử dụng giao diện và một nhà máy để tạo ra các thể loại không xác định (bất kỳ loại nào thực hiện giao diện), thì sẽ nhanh hơn để hạn chế mọi người lập trình chống lại giao diện và nhà máy ở phía trước thay vì tham chiếu đến MyImpl với tham chiếu đến IMyInterface sau, v.v.

Vì vậy, khi viết phần mềm mới, đó là một cuộc gọi phán đoán có lập trình chống lại giao diện hay triển khai hay không, trừ khi bạn đã quen với những gì có thể xảy ra loại phần mềm đó dựa trên kinh nghiệm trước đó.

Tôi thường giữ nó "trong thông" trong một thời gian cho dù tôi có giao diện, lớp cơ sở hay cả hai và thậm chí lớp cơ sở có trừu tượng hay không (thường là). Tôi sẽ làm việc trên một dự án (thường là một giải pháp Visual Studio với khoảng 3 đến 10 dự án trong đó) trong một thời gian (một vài ngày, có thể) trước khi tôi refactor và/hoặc yêu cầu một ý kiến ​​thứ hai. Khi đã đạt được quyết định cuối cùng và mã được tái cấu trúc và thử nghiệm, tôi nói với các nhà phát triển đồng nghiệp rằng nó đã sẵn sàng để sử dụng.

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