Có phải là một thực tiễn xấu khi có nhiều lớp trong cùng một tệp?


81

Tôi đã từng có một lớp cho một tệp. Ví dụ car.csxe hạng . Nhưng khi tôi lập trình nhiều lớp hơn, tôi muốn thêm chúng vào cùng một tệp. Ví dụ: car.cs có hạng xe và hạng cửa , v.v.

Câu hỏi của tôi là tốt cho Java, C #, PHP hoặc bất kỳ ngôn ngữ lập trình nào khác. Tôi có nên thử không có nhiều lớp trong cùng một tệp hay không?

Câu trả lời:


93

Tôi nghĩ bạn nên cố gắng giữ cho mã của mình ở 1 lớp cho mỗi tệp.

Tôi đề nghị điều này vì sẽ dễ dàng tìm thấy lớp học của bạn hơn sau này. Ngoài ra, nó sẽ hoạt động tốt hơn với hệ thống kiểm soát nguồn của bạn (nếu một tệp thay đổi, thì bạn biết rằng một lớp cụ thể đã thay đổi).

Lần duy nhất tôi nghĩ việc sử dụng nhiều hơn một lớp cho mỗi tệp là đúng khi bạn đang sử dụng các lớp nội bộ ... nhưng các lớp nội bộ nằm bên trong một lớp khác và do đó có thể được để bên trong cùng một tệp. Các vai trò của các lớp bên trong có liên quan chặt chẽ đến các lớp bên ngoài, vì vậy việc đặt chúng trong cùng một tệp là tốt.


1
Sau khi thấy những gì kotlin có thể làm trong một tệp, tôi bắt đầu tin rằng một số thứ như DTO có thể có trong một tệp.
John Tribe

1
Thêm vào đó, các lớp bạn có trong cùng một tệp thường có liên quan chặt chẽ với nhau, điều này có thể gây khó khăn cho việc chỉnh sửa vì không dễ xem nhiều lớp đồng thời. Bạn phải cuộn xung quanh rất nhiều. Chế độ xem phân tách sẽ hữu ích, nhưng nó không dễ dàng như chỉ có một cửa sổ riêng biệt cho từng tệp / lớp.
Chad Hedgcock

Điều gì về tự động tải? Khi xác định nhiều lớp trong một tệp nguồn, chức năng tự động tải sẽ trở nên phức tạp hơn. xem stackoverflow.com/questions/37982012/…
Alexander Behling

26

Trong Java, một lớp công khai trên mỗi tệp là cách ngôn ngữ hoạt động. Một nhóm các tệp Java có thể được thu thập thành một gói.

Tuy nhiên, trong Python, các tệp là "mô-đun" và thường có một số lớp liên quan chặt chẽ. Một gói Python là một thư mục, giống như một gói Java.

Điều này mang lại cho Python một cấp độ nhóm bổ sung giữa lớp và gói.

Không có câu trả lời đúng nào là ngôn ngữ bất khả tri. Nó thay đổi theo ngôn ngữ.


23

Một lớp cho mỗi tệp là một quy tắc tốt, nhưng sẽ thích hợp để thực hiện một số ngoại lệ. Ví dụ: nếu tôi đang làm việc trong một dự án mà hầu hết các lớp đều có các loại tập hợp được liên kết, thường thì tôi sẽ giữ lớp và tập hợp của nó trong cùng một tệp, ví dụ:

public class Customer { /* whatever */ }

public class CustomerCollection : List<Customer> { /* whatever */ }

Nguyên tắc chung tốt nhất là giữ một lớp cho mỗi tệp trừ khi điều đó bắt đầu khiến mọi thứ khó hơn thay vì dễ dàng hơn. Vì tính năng Tìm trong Tệp của Visual Studio rất hiệu quả, bạn có thể sẽ không phải mất nhiều thời gian để xem qua cấu trúc tệp.


3
Đây là lời khuyên tồi. Thực hiện lời khuyên của câu trả lời được chấp nhận. Bạn nên tách kho lưu trữ đối tượng khỏi lớp bạn đang lưu. Nó chỉ đơn giản là tạo ra sự nhầm lẫn không đáng có.
Hudson

4
@Hudson Tôi không thấy bất kỳ mã "kho lưu trữ đối tượng" nào ở trên.
Ryan Lundy

18

Không, tôi không nghĩ đó là một thực hành hoàn toàn xấu. Ý tôi là nói chung, tốt nhất nên có một tệp riêng cho mỗi lớp, nhưng chắc chắn có những trường hợp ngoại lệ tốt hơn là có nhiều lớp trong một tệp. Một ví dụ điển hình về điều này là một nhóm các lớp Ngoại lệ, nếu bạn có một vài chục lớp trong số này cho một nhóm nhất định thì có thực sự hợp lý khi tạo một tệp riêng biệt cho mỗi hai lớp lót không? Tôi sẽ tranh luận là không. Trong trường hợp này, việc có một nhóm các ngoại lệ trong một lớp là IMHO ít rườm rà và đơn giản hơn nhiều.


10

Tôi nhận thấy rằng bất cứ khi nào tôi cố gắng kết hợp nhiều loại vào một tệp duy nhất, tôi luôn kết thúc việc quay lại và tách chúng ra đơn giản vì nó giúp chúng dễ tìm hơn. Bất cứ khi nào tôi kết hợp, cuối cùng luôn có một khoảnh khắc mà tôi đang cố gắng tìm ra wtf mà tôi đã xác định kiểu x.

Vì vậy, bây giờ, quy tắc cá nhân của tôi là mỗi kiểu riêng lẻ (ngoại trừ có thể đối với các lớp con, theo đó nghĩa là một lớp bên trong một lớp, không phải lớp kế thừa) nhận được tệp riêng của nó.


9

IDE của bạn cung cấp cho bạn chức năng " Điều hướng đến " và bạn có một số quyền kiểm soát đối với không gian tên trong các lớp của mình nên những lợi ích dưới đây của việc có nhiều lớp trong cùng một tệp là khá xứng đáng đối với tôi.

Lớp cha - con

Trong nhiều trường hợp, tôi thấy khá hữu ích khi có các lớp Kế thừa trong tệp Lớp Cơ sở của chúng .

Sau đó, khá dễ dàng để xem thuộc tính và phương thức nào mà lớp con của bạn kế thừa và tệp cung cấp tổng quan nhanh hơn về chức năng tổng thể.

Công cộng: Nhỏ - Người trợ giúp - Lớp DTO

Khi bạn cần một số lớp đơn giảnnhỏ cho một chức năng cụ thể, tôi thấy khá thừa khi có một tệp với tất cả các tham chiếu và chỉ bao gồm cho một lớp 4-8 Liner .....

Điều hướng mã cũng dễ dàng hơn chỉ cần cuộn qua một tệp thay vì chuyển đổi giữa 10 tệp ... Việc cấu trúc lại cũng dễ dàng hơn khi bạn phải chỉnh sửa chỉ một tham chiếu thay vì 10 .....

Nhìn chung, việc phá vỡ quy tắc Sắt về 1 lớp cho mỗi tệp cung cấp thêm một số quyền tự do để tổ chức mã của bạn.

Điều gì xảy ra sau đó, thực sự phụ thuộc vào IDE, Ngôn ngữ, Kỹ năng Giao tiếp Nhóm và Tổ chức của bạn.

Nhưng nếu bạn muốn tự do đó tại sao phải hy sinh nó cho một quy tắc sắt?


7

Nếu bạn đang làm việc theo nhóm, việc giữ các lớp trong các tệp riêng biệt giúp kiểm soát nguồn dễ dàng hơn và giảm nguy cơ xung đột (nhiều nhà phát triển thay đổi cùng một tệp cùng một lúc). Tôi nghĩ rằng nó cũng giúp bạn tìm thấy mã bạn đang tìm kiếm dễ dàng hơn.


7

Quy tắc tôi luôn áp dụng là có một lớp chính trong một tệp có cùng tên. Tôi có thể bao gồm hoặc không bao gồm các lớp trợ giúp trong tệp đó tùy thuộc vào mức độ chúng được kết hợp chặt chẽ với lớp chính của tệp. Các lớp hỗ trợ là độc lập hay chúng tự hữu ích? Ví dụ: nếu một phương thức trong một lớp cần một phép so sánh đặc biệt để sắp xếp một số đối tượng, tôi không bận tâm một chút nào khi gộp lớp chức năng so sánh vào cùng một tệp với phương thức sử dụng nó. Tôi sẽ không mong đợi sử dụng nó ở nơi khác và nó không có ý nghĩa gì nếu nó tự sử dụng.


6

Nó có thể không tốt từ quan điểm của sự phát triển và khả năng bảo trì trong tương lai. Sẽ dễ dàng hơn nhiều để nhớ vị trí của lớp Xe nếu bạn có lớp Car.cs. Bạn sẽ tìm lớp Widget ở đâu nếu Widget.cs không tồn tại? Nó là một phụ tùng xe hơi? Nó có phải là một tiện ích động cơ không? Ồ có lẽ đó là một phụ tùng bánh mì tròn.


2
Như đã đề cập trong stackoverflow.com/questions/360643/… , với các công cụ điều hướng phổ biến, bạn không phải điều hướng theo tệp. Thay vào đó, bạn điều hướng theo lớp học / thành viên.
Suma

6

Lần duy nhất tôi xem xét các vị trí tệp là khi tôi phải tạo các lớp mới. Nếu không, tôi không bao giờ điều hướng theo cấu trúc tệp. Tôi Sử dụng "đến lớp" hoặc "đi đến định nghĩa".

Tôi biết đây là một phần của vấn đề đào tạo; Việc giải phóng bản thân khỏi cấu trúc tệp vật lý của các dự án đòi hỏi phải thực hành. Nó rất bổ ích mặc dù;)

Nếu cảm thấy tốt khi đặt chúng vào cùng một tệp, hãy là khách của tôi. Không thể làm điều đó với các lớp công khai trong java;)


2

Theo nguyên tắc chung, một lớp / một tệp là cách để đi. Tuy nhiên, tôi thường giữ một số định nghĩa giao diện trong một tệp. Nhiều lớp trong một tệp? Chỉ khi chúng có liên quan rất chặt chẽ bằng cách nào đó, và rất nhỏ (<5 phương thức và thành viên)


2

Đúng như vậy, rất nhiều thời gian trong lập trình, nó phụ thuộc rất nhiều vào tình huống.

Ví dụ, tính liên kết của các lớp được đề cập là gì? Chúng có liên kết chặt chẽ với nhau không? Chúng có hoàn toàn trực giao không? Chúng có liên quan đến chức năng không?

Sẽ không nằm ngoài dòng đối với một khung công tác web để cung cấp một widget có mục đích chung. Bất kỳ tệp nào chứa BaseWidget, TextWidget, CharWidget, v.v.

Người dùng khung công tác sẽ không quá khó khăn trong việc xác định tệp more_widgets để chứa các tiện ích bổ sung mà họ thu được từ các tiện ích khung cho không gian miền cụ thể của họ.

Khi các lớp trực giao và không liên quan gì đến nhau, việc nhóm thành một tệp thực sự sẽ là giả tạo. Giả sử một ứng dụng để quản lý một nhà máy sản xuất robot chế tạo ô tô. Một tệp được gọi là các bộ phận chứa CarParts và RobotParts sẽ là vô nghĩa ... không có nhiều khả năng liên quan giữa việc đặt hàng các bộ phận thay thế để bảo trì và các bộ phận mà nhà máy sản xuất. Việc tham gia như vậy sẽ không thêm thông tin hoặc kiến ​​thức về hệ thống bạn đang thiết kế.

Có lẽ quy tắc ngón tay cái tốt nhất là không hạn chế lựa chọn của bạn bằng quy tắc ngón tay cái. Các quy tắc ngón tay cái được tạo ra để phân tích lần đầu tiên, hoặc để hạn chế lựa chọn của những người không có khả năng đưa ra lựa chọn tốt. Tôi nghĩ hầu hết các lập trình viên đều muốn tin rằng họ có khả năng đưa ra quyết định tốt.


2

Bạn nên hạn chế làm như vậy, trừ khi bạn có lý do chính đáng.

Một tệp có nhiều lớp nhỏ liên quan có thể dễ đọc hơn một số tệp. Ví dụ, khi sử dụng 'các lớp trường hợp', để mô phỏng các kiểu liên hợp, có một mối quan hệ chặt chẽ giữa mỗi lớp. Sử dụng cùng một tệp cho nhiều lớp có lợi thế là nhóm chúng lại với nhau một cách trực quan cho người đọc.

Trong trường hợp của bạn, một chiếc xe hơi và một cánh cửa dường như không có liên quan gì cả và việc tìm kiếm loại cửa trong tệp car.cs sẽ là điều bất ngờ, vì vậy đừng.


1

Một lớp cho mỗi tệp đơn giản hơn để duy trì và rõ ràng hơn nhiều cho bất kỳ ai khác nhìn vào mã của bạn. Nó cũng là bắt buộc hoặc rất hạn chế ở một số ngôn ngữ.

Ví dụ, trong Java, bạn không thể tạo nhiều lớp cấp cao nhất cho mỗi tệp, chúng phải nằm trong các tệp riêng biệt mà tên lớp và tên tệp giống nhau.


1

Câu trả lời của Smalltalk là: bạn không nên có tệp (để lập trình). Chúng làm cho việc lập phiên bản và điều hướng trở nên khó khăn.

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.