2010-01-26 28 views
21

Gần đây tôi đã nhìn thấy một số mã C# mà tuyên bố giao diện và thực hiện nơi trong cùng một tập tin, như thế nàyGiao diện C# và triển khai trong cùng một tệp - ý tưởng hay?

namespace MyNameSpace.Foo 
{ 
    public interface IFoo{ 
     void DoThis(); 
    } 
    public class Foo : IFoo { 
     public void DoThis(); 
    } 
} 

Thoạt nhìn có vẻ như tất cả các sai lầm khi có tuyên bố và thực hiện trong cùng một tập tin, nhưng có một thực tế lợi ích. ví dụ. Khi bạn đi đến định nghĩa trong Visual Studio giao diện và thực hiện có trong cùng một tập tin. Cách tiếp cận này không cấm bạn thực hiện các giao diện khác, chẳng hạn như có thể cần thiết để kiểm tra đơn vị. Đối với các giao diện chỉ có một triển khai, tôi nghĩ rằng đây có thể là một cách tiếp cận thực dụng.

Ý tưởng hay hay?

Mở rộng câu hỏi:
Làm thế nào để người sử dụng Visual Studio để điều hướng đến một thực hiện khi bạn có một tài liệu tham khảo giao diện IFoo myFoo = FooFactory.getFoo(MY_FOO); Nếu tôi phải bấm vào IFoo và chọn Go To Definition tôi có thể nhận tờ khai giao diện. Có cách nào để tôi có được danh sách triển khai IFoo vì đó là điều tôi thực sự quan tâm đến.

+1

Nhận xét tuyệt vời cho đến thời điểm này. Tôi nghĩ rằng câu hỏi của tôi nên đã được mở rộng để hỏi làm thế nào mọi người sử dụng Visual Studio để điều hướng đến một thực hiện khi bạn có một tham chiếu giao diện: IFoo myFoo = FooFactory.getFoo (MY_FOO); Nếu tôi nhấp chuột phải vào IFoo và chọn Go To Definition, tôi có thể nhận khai báo giao diện Có cách nào để tôi có được danh sách triển khai IFoo vì đó là những gì tôi thực sự quan tâm đến. – Paul

Trả lời

33

Đề xuất của tôi là luôn tuân theo quy tắc của một mục cho mỗi tệp .cs, có thể là khai báo, giao diện hoặc lớp liệt kê. Tên của tệp .cs phải khớp với tên của nội dung chứa.

Quy tắc đơn giản, dễ theo dõi. Chúng tôi sử dụng StyleCop nội bộ để cảnh sát này.

Nếu bạn kết hợp phương pháp này với việc sử dụng không gian tên hợp lý thì điều đó có nghĩa là chế độ xem trình khám phá giải pháp của bạn trong Visual Studio giúp dễ dàng điều hướng các thành phần trong dự án của bạn. Lưu ý rằng ReSharper gives an alternative approach để điều hướng này, nhưng sử dụng điều này không phải là sở thích của mọi người (và không phải tất cả mọi người có thể có một Add-In như ReSharper).

Travis G đã hỏi về các điểm tốt hơn như các đại biểu và khai báo EventArgs tùy chỉnh. Vì EventArgs tùy chỉnh là các lớp, tôi sẽ đặt chúng trong các tệp riêng của chúng (một lần nữa, giữ nguyên quy tắc đơn giản). Các đại biểu tôi sẽ tuyên bố với lớp sử dụng chúng. Nếu tôi thấy tôi có rất nhiều đại biểu đã được sử dụng ở nhiều nơi tôi có thể xem xét việc đặt tất cả chúng trong một tập tin Delegates.cs (đôi khi tôi làm điều này với hằng số, trong một tập tin Consts.cs).

Tuy nhiên, một số điều này chắc chắn là chủ quan và đi vào cõi của phần mềm religious wars.

+1

Tôi hỗ trợ điều này. Nó giúp giảm bớt việc duyệt mã cũng như tìm kiếm một lớp hoặc giao diện cụ thể: chỉ cần nhìn vào tên tệp. –

+2

Tôi ở bên bạn, nhưng bạn làm gì cho những thứ nhỏ như 'delegate' và 'EventArg'? Tôi thường đặt chúng vào cùng một tệp, vì chúng chỉ được sử dụng ở một nơi. –

+0

Hãy chắc chắn rằng bạn hài lòng với những gì bạn đang làm trước khi bạn cho phép chia sẻ lại. Nó rất tuyệt và tôi sử dụng nó nhưng với sức mạnh to lớn thì có trách nhiệm lớn lao. –

13

Cá nhân ...

Nếu một giao diện chỉ có khả năng (trong ngắn hạn) được sử dụng cho một lớp (giống như khi cung cấp một giao diện cho dependency injection) sau đó tôi sẽ đặt nó ở phía trên cùng của tệp lớp. Trong quá trình phát triển (khi lớp học có thể thay đổi) đó là một PITA phải thay đổi hai tệp mỗi khi bề mặt công cộng thay đổi.

Tất nhiên, nếu có khả năng giao diện sẽ được thực hiện bởi nhiều hơn một lớp thì tôi đặt nó vào một tệp riêng biệt.

+4

Vâng, đây là kịch bản tôi đã nghĩ đến, khi bạn chỉ sử dụng một giao diện cho các lý do DI và không có nhiều cơ hội bạn sẽ thực hiện định nghĩa khác của giao diện ngoài việc kiểm tra impl. – Paul

+2

'Nếu một giao diện chỉ có thể được sử dụng cho một lớp' bạn đang làm sai. Giao diện là vô giá trị ở đây. Nếu nhiều lớp không triển khai giao diện ngay lập tức, bạn đang làm sai. Dependency Injection KHÔNG CẦN các giao diện vô nghĩa. Đây là một huyền thoại. Sử dụng các loại bê tông thực tế. –

+5

@ChrisMarisic Làm thế nào bạn sẽ cung cấp mocks phụ thuộc để kiểm tra đơn vị nếu phụ thuộc cho biết không phải là giao diện? – Holf

7

Việc định nghĩa và triển khai giao diện trong cùng một tệp không liên quan đến kiểm tra đơn vị, vì giao diện đó sẽ có sẵn ở bất kỳ đâu.

Tôi thường bắt đầu bằng giao diện và triển khai đơn giản trên cùng một tệp. Khi mọi thứ lớn lên, tôi chia chúng khi mã khác cần tham chiếu đến giao diện đó.

4

Tôi chỉ muốn tuân theo quy tắc "một lớp, một tệp".Với lớp tôi cũng có nghĩa là giao diện, enums, v.v.

Và điều gì sai khi đặt con trỏ lên tên giao diện và nhấn F12?

1

Chắc chắn không có hại gì khi làm như vậy và các công cụ như chia sẻ lại sẽ thực hiện việc triển khai bên dưới giao diện trong mã. Tuy nhiên, họ cũng cung cấp cho bạn tùy chọn để di chuyển sự thực hiện vào một tệp khác.

Bạn nói đúng, nó không ngăn bạn khai thác lợi ích của giao diện để kiểm tra đơn vị, nhưng bạn có thể muốn xem xét việc đưa giao diện vào một hội đồng khác hoàn toàn. Bằng cách đó bạn có thể lập trình chống lại các giao diện và triển khai hoán đổi theo ý muốn, giúp bạn tách biệt hơn. Như bao giờ không có câu trả lời đúng hay sai, nó chỉ đi xuống đến những gì bạn đang cố gắng đạt được.

+1

Mẹo hay về cách đặt giao diện trong một hội đồng riêng biệt (dự án), hoạt động tốt cho tôi. – Paul

0

Tôi làm điều đó trong java cho các giao diện nhỏ với một vài phương pháp. Trong trường hợp này, tôi cung cấp một hoặc nhiều triển khai cơ bản trong tệp giao diện.

Điều này tránh các lớp học nhỏ rải rác xung quanh.

Nhưng tôi không thể nói đó là thực tiễn tốt hay xấu, mặc dù đồng nghiệp của tôi không bao giờ phàn nàn.

5

Tôi coi đây là một ý tưởng tồi.

Giữ riêng giao diện và triển khai. Nếu không thì có khả năng bạn sẽ làm hỏng thiết kế. Bao gồm các tập tin và tự động nhận được thực hiện ngay cả khi bạn chỉ muốn giao diện, sau đó vô tình (vì nó là thuận tiện) sử dụng Impl thay vì giao diện và yay, đóng khớp nối.

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