hginit - #ifdefs thật lố bịch


8

Tôi đang đọc phần giới thiệu đồng bóng của Joel Spolsky khi nó xuất hiện:

"Và bây giờ những gì họ làm là thế này: mỗi tính năng mới nằm trong một khối #ifdef lớn. Vì vậy, họ có thể làm việc trong một thân cây duy nhất, trong khi khách hàng không bao giờ thấy mã mới cho đến khi nó được gỡ lỗi, và thật lòng mà nói, thật nực cười."

Tại sao điều này thật vô lý , không phải thế này, nếu không có gì khác, đơn giản hơn để xử lý? Không có gì lạ mắt nhưng thực hiện mánh khóe - ít nhất là nếu bạn đã "kết hôn" với lật đổ.

Nhược điểm là gì? Tôi không thể tranh luận.


Nó không phải là vô lý khi bạn chỉ có một hoặc hai công tắc, nhưng tôi đã phải đối phó với các chuỗi lớn các nhóm ifdefs lồng vào nhau một cách kỳ lạ và đó là một sự ghê tởm để cố gắng hiểu, và nếu bạn phải đối phó với nó, bạn sẽ phải đối phó với nó thấy nó vô lý quá Bạn nghĩ rằng mã mẫu tăng cường phức tạp rất khó đọc ......
tên gì là

Câu trả lời:


20

Tôi nghĩ rằng câu trả lời được đưa ra trong câu tiếp theo:

Giữ ổn định và mã dev riêng biệt là chính xác những gì kiểm soát mã nguồn được cho là để cho phép bạn làm.

Bằng cách sử dụng #ifdefcác khối, bạn đang mô phỏng chức năng của hệ thống kiểm soát nguồn với bộ tiền xử lý C. Đó là công cụ sai cho công việc.

Nhược điểm là bạn có thể sẽ sao chép rất nhiều mã (nghĩ về toàn bộ định nghĩa hàm một lần bên trong, một lần bên ngoài #ifdef) hoặc có mã không thể đọc được (nghĩ về các #ifdefdòng đơn kèm theo trong một hàm - có thể lặp đi lặp lại).

Trong biến thể đầu tiên, bạn sẽ sửa lỗi hai lần (điều này là không cần thiết nếu bạn chỉ có thể hợp nhất các lỗi từ nhánh ổn định sang nhánh dev), trong khi đó, mục tiêu ban đầu là tách các nhánh dev và dev không thực sự đạt được .


2
+1: Vào những năm 80, tôi có một trình gỡ lỗi chạy trên hầu hết mọi hệ thống UNIX mà bạn có thể nghĩ tới. Trước phiên bản 4, mã đã được cập nhật #ifdefs. Tôi thề là nó làm mắt tôi chảy máu khi nhìn nó. Đối với phiên bản 4, tôi đã đi đến một kiến ​​trúc có thể cắm bằng các tệp riêng biệt và cũng bắt đầu sử dụng RCS (hoặc đó là SCCS?). Cuộc sống trở nên tốt hơn và các tính năng mới dễ dàng phát triển hơn nhiều. (Nhưng chàng trai nào tôi từng ước chúng ta có git hoặc hg trong những ngày đó.)
Peter Rowell

Tôi biết địa ngục #ifdef từ kinh nghiệm! Tôi đồng ý rằng nên tránh việc thay thế kiểm soát phiên bản.
Giorgio

3

Sau khi duy trì mã mà là một tổ chuột của #ifdefs (mặc dù vì lý do khác nhau), nó vô lý; nó làm cho mã khó đọc hơn và khó bảo trì hơn nhiều, đặc biệt là khi thử nghiệm với nhiều điều kiện.


Vâng, tôi cũng đã làm điều này và nó thật tồi tệ.
gièm pha

1

Nó giả định tất cả các mã mới có thể được viết mà không cần chạm vào mã hiện có. Thường thì cách duy nhất để làm điều đó là lặp lại bản thân của bạn rất nhiều. (một phương thức mới cho một phương pháp tương tự nhưng không hoàn toàn giống nhau chẳng hạn).

Một trong những lợi thế chính của VCS phân tán là khuyến khích nhóm làm việc trên nhánh tính năng của riêng họ và không lo lắng về công việc của bạn xung đột với người khác. Chiến lược này phủ nhận lợi thế đó.

Đối với tôi nó có vẻ vô lý vì dường như họ đang cố tình lạm dụng các công cụ. Nếu bạn sẽ thực hiện chuyển đổi chắc chắn nó đáng để học cách sử dụng chúng.


3
điều này không giới hạn ở DVCS
James

Không, nó không cho rằng. Ngay cả với các vị trí chiến lược #ifdef, bạn có thể chạm vào mã hiện có nhưng vẫn giữ nguyên phiên bản cũ #else.
tdammers

1

#ifdefMã ed không vô lý, nhưng - buồn và khủng khiếp. Và đó là (ngày nay) chẩn đoán cho nhà phát triển

Chà, Joel đã chọn trong "Subversion Re-learning" The Bad Way (tm) của tranh luận - anh ta đã tạo ra tình huống đặc biệt, thoái hóa với những người dùng được chọn đặc biệt và sử dụng trường hợp sử dụng này như một sự biện minh cho luận án "Subversion suxx"

Spux-code suxx nhiều hơn, mã không thể quản lý và không thể đọc được là nguy hiểm hơn so với việc dành thời gian để giáo dục lại "Hợp nhất đúng" trong Subversion - "Hợp nhất thường xuyên, morons !!!" Hợp nhất phân nhánh và hai chiều có thể và có thể sử dụng được trong Subversion <1.5, bây giờ (sau khi giới thiệu mergeinfo), việc hợp nhất trở nên dễ dàng và thoải mái hơn . Chi phí giám sát cây "thú vị" và hợp nhất đồng bộ hóa (thường !!!) là mức giá hợp lý cho nhà phát triển, trả lại mã nhỏ gọn, sạch, có thể sửa lỗi.


1

Những gì anh ta đang mô tả thực sự là một FeatureToggle và có thể có những lý do chính đáng để sử dụng nó thay vì các nhánh tính năng. Vấn đề là với việc sử dụng #ifdef. Nếu không có sự quản lý tốt, họ có thể dễ dàng trở thành một mớ hỗn độn lớn nằm rải rác xung quanh cơ sở mã.

Hãy xem xét những điều sau đây:

  1. Khi nào bạn loại bỏ một #ifdef? - Bạn có chắc chắn không còn bản dựng nào mà vẫn loại trừ tính năng đó không? Cũng không phải cho một khách hàng (trả tiền tốt) cho những người bạn thực hiện một số bản dựng đặc biệt?
  2. Ai chịu trách nhiệm loại bỏ #ifdef? - Nhà phát triển đã tạo ra tính năng này? Bạn có chắc chắn anh ấy sẽ nhớ 4 tuần xuống, để kiểm tra xem công tắc không bị loại trừ trong bất kỳ bản dựng nào và có thể được gỡ bỏ một cách an toàn không? Anh ta sẽ tự tin rằng nó là an toàn để loại bỏ #ifdef? Thế còn nhiệm vụ cực kỳ cấp bách khác, không ưu tiên loại bỏ bệnh sởi #ifdefthì sao?

Kinh nghiệm của tôi nói rằng những thứ như vậy #ifdefsẽ nằm xung quanh mãi mãi, xả rác bừa bãi.


1

Từ kinh nghiệm (trên một dự án lớn trong cơ sở mã hơn 600.000 dòng, đã không được phát hành trong 3 năm bằng cách sử dụng #ifdef) các đối số của tôi chống lại việc sử dụng chúng sẽ là:

  • Chúng làm giảm khả năng đọc mã - đặc biệt khi một số IDE khăng khăng đặt chúng ở đầu dòng bỏ qua mức thụt lề.
  • Chúng thêm phức tạp, cả cho các nhà phát triển làm việc trên tính năng tách biệt và cho các nhà phát triển đang cố gắng làm việc xung quanh họ.
  • Sự phức tạp bổ sung đó làm chậm năng suất - trong trường hợp của chúng tôi, tôi tin rằng nó đã thêm vài tháng vào dự án.
  • Xóa chúng một khi tính năng được phát hành không phải là một nhiệm vụ chi phí bằng 0 - trong trường hợp của chúng tôi, đó là một nhiệm vụ kéo dài một tuần để ai đó trải qua và xóa tất cả các #ifdefs và giải quyết xung đột với mã đã được thêm vào trong #elseifs.

Nói chung, đó là một ngày tuyệt vời khi chúng tôi di cư đến Mercurial - chúng tôi vẫn có một cơ sở mã khổng lồ, quá phức tạp, nhưng ít nhất chúng tôi có thể phân nhánh hiệu quả ngay bây giờ.

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.