Nhiều lớp trong một tệp .cs - tốt hay xấu? [đóng cửa]


30

Có nên tạo nhiều lớp trong một tệp .cs hay mỗi tệp .cs nên có một lớp riêng?

Ví dụ:

public class Items
{
    public class Animal
    {
    }

    public class Person
    {
    }

    public class Object
    {
    }
}

Lẩn tránh thực tế trong một phút rằng đây là một ví dụ nghèo nàn về kiến ​​trúc tốt, có nhiều hơn một lớp trong tệp .cs có mùi mã không?

Câu trả lời:


30

Ví dụ bạn đưa ra thực sự tốt theo quan điểm của tôi. Bạn đang khai báo các lớp bên trong , vì vậy việc giữ chúng trong cùng một tệp là hoàn toàn hợp lý . Cách duy nhất để làm điều này là làm cho Itemslớp của bạn thành một lớp một phần và chia nó thành nhiều tệp. Tôi sẽ xem xét thực hành xấu này. Chính sách chung của tôi cho các lớp lồng nhau là chúng phải nhỏ và riêng tư. Có hai trường hợp ngoại lệ:

  • bạn đang thiết kế một cụm lớp (phổ biến hơn trong object-c), do đó có thể hợp lý khi sử dụng cách tiếp cận lớp một phần
  • bạn cần một enum chỉ được sử dụng với API công khai của lớp cha. Trong trường hợp này, tôi thích có một enum công khai được khai báo bên trong lớp cha thay vì làm ô nhiễm không gian tên của tôi. Enum là một "enum bên trong" có hiệu quả dẫn đến việc cung cấp cho nó một phạm vi được xác định rõ.

Nếu bạn đặt câu hỏi khác một chút và hỏi về "Tôi có nên đặt từng lớp không gian tên vào tệp riêng của mình không" thì câu trả lời của tôi sẽ là "có".

Khi thiết kế các lớp học, chúng tôi tôn trọng Nguyên tắc Trách nhiệm duy nhất. Đọc mã trở nên dễ dàng hơn rất nhiều nếu hình dạng của nó tuân theo ngữ nghĩa của nó, do đó việc chia tệp theo lớp là hợp lý.

Từ quan điểm cơ học, có một tệp cho mỗi lớp có một số lợi thế. Bạn có thể mở nhiều lớp cùng một lúc trong các cửa sổ khác nhau. Điều này đặc biệt quan trọng vì không có nhà phát triển nghiêm túc nào làm việc với ít hơn hai màn hình. Có thể có bối cảnh ở phía trước đầu của tôi có nghĩa là tôi có thể giữ bối cảnh nhiều hơn trong đầu tôi. (Hầu hết các IDE sẽ cho phép bạn mở cùng một tệp hai lần, nhưng tôi thấy điều này thật bất tiện).

Khía cạnh quan trọng tiếp theo là kiểm soát nguồn và sáp nhập. Bằng cách giữ các lớp riêng biệt, bạn tránh được nhiều rắc rối khi thay đổi cùng một tệp được thực hiện vì các lớp riêng biệt cần được thay đổi.


1
Tôi đồng ý, nhưng sau đó một lần nữa các lớp học bên trong là rất hiếm trong kinh nghiệm của tôi. Công bằng mà nói, thực sự không có gì có thể thực sự biện minh cho các lớp bên trong, trường hợp duy nhất tôi biết là vô số các lớp mà bạn không thực sự về lớp thực tế miễn là bạn có thể liệt kê nó. Trong tất cả các trường hợp khác, mỗi lớp sẽ nhận được tệp riêng của nó. Nếu không có lý do khác vì vấn đề kiểm soát nguồn.
Homde

2
Tôi muốn thêm rằng các lớp bên trong phải là một ngoại lệ hiếm hoi và hầu như không bao giờ nên công khai.
Josh

Yup dạy tôi vì đã quá nhanh chóng, các lớp bên trong vẫn ổn, tuy nhiên việc hỏi bạn có nên sử dụng innerclass hay không là một câu hỏi khác :)
krystan vinh dự

11

Để trung thực một cách tàn nhẫn, xin vui lòng không thêm nhiều hơn một lớp gốc vào một tệp. Ở công việc cuối cùng của tôi, có các tệp không chỉ có nhiều lớp, mà còn có nhiều không gian tên và điều này trải dài trong hàng ngàn dòng mã. Rất khó để cố gắng làm theo.

Nếu có các lớp có liên quan chặt chẽ với nhau, thì hãy đặt tên tệp của chúng tương tự hoặc đặt chúng vào thư mục con.

Sự tách biệt vật lý của các tệp lớp giúp (lưu ý, không phải là kết thúc tất cả) tạo ra sự phân tách mối quan tâm và khớp nối lỏng lẻo hơn.

Mặt khác, ví dụ của bạn không hiển thị nhiều hơn một lớp gốc. Có một số lớp lồng nhau (lưu ý: cố gắng không tạo các lớp lồng nhau bất cứ điều gì nhưng privatenếu bạn có thể thiết kế lớp này) và điều này là hoàn toàn tốt để có trong một tệp.


3
Trời ơi - nghe thật kinh khủng.

Tại sao cậu lại hỏi? Có ai đó đánh giá thấp bạn và bạn muốn hỏi tại sao?

Đợi đã ... bạn đang đề cập đến giai thoại nhỏ về công việc cuối cùng của tôi? Nếu vậy, tôi hiểu sai và xin lỗi vì như vậy.
Jesse C. Choper

Hoan toan Đông y. Tôi đang làm việc trên một dự án nơi hầu hết các tệp có ít nhất 4 lớp cho mỗi tệp. Và một số có tới 22 lớp + 1 giao diện cho mỗi tệp.
L_7337

7

Nếu các tệp có tính gắn kết cao, ví dụ, trong đó nó là một thay thế cho việc có một số tệp rất ngắn, có tên tương tự, thì đó có thể là một ý tưởng tốt.

Chẳng hạn, tôi thấy rằng khi sử dụng Fluent NHibernate sẽ dễ dàng hơn nếu tôi giữ EntityEntityMaptrong một tệp duy nhất, bất chấp những gì công cụ của tôi có thể nói về điều đó.

Trong hầu hết các trường hợp, nó chỉ làm cho các lớp khó tìm hơn. Sử dụng một cách tiết kiệm và thận trọng.


1
Cụ thể đối với Fluent NHibernate, tôi thấy hữu ích khi giữ chúng không chỉ trong cùng một tệp mà còn cùng một lớp. Tất cả các thực thể của tôi có một lớp lồng nhau được gọi là Bản đồ.
James Beninger

7

Đơn giản chỉ cần đặt có, hình thức không tốt để làm điều này và tôi sẽ cho bạn biết lý do, một lát sau khi giải pháp của bạn trở nên lớn, bạn sẽ quên các lớp ở đâu vì tên tệp sẽ không còn thể hiện nội dung là gì, tên tệp là gì AnimalPersonObject.cs chỉ là không khả thi.

Chắc chắn bạn có thể khắc phục điều này bằng cách sử dụng các tính năng trong các công cụ như chia sẻ lại để chuyển sang các loại, nhưng 1 lớp trên mỗi tệp (bao gồm cả giao diện) thực sự là xương sống của bất kỳ tiêu chuẩn mã nào tôi từng thấy, không chỉ trong .net mà trong java và c ++ và rất nhiều ngôn ngữ khác, những ngôn ngữ thường không có vấn đề về bảo trì và bạn sẽ thấy các nhà phát triển cơ sở cảm thấy khó nắm bắt mã.

Hầu như tất cả các công cụ tối ưu hóa mã sẽ bảo bạn chuyển các lớp thành một tệp riêng biệt, vì vậy đối với tôi, đây là mùi mã và cần một số loại bỏ để trung hòa nó :)


3

Một vấn đề khác là với các lớp rất lớn và tương tự trong cùng một tệp - khi bạn không thể thấy khai báo lớp mọi lúc - cuối cùng bạn có thể đặt các điểm dừng vào lớp sai và tự hỏi tại sao chúng không bị tấn công ... ôi! :)


-3

Về cơ bản, nếu bạn chỉ cần sử dụng lớp này từ bên trong lớp "cha mẹ" (về phạm vi), thì nó thường được sử dụng để định nghĩa nó là một lớp lồng nhau.

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.