DRY không liên quan, nhưng mã gần như giống hệt nhau


34

Tôi có một số mã gần giống nhau, nhưng sử dụng các loại hoàn toàn khác nhau, không có sự kế thừa giữa chúng, trên biến chính. Cụ thể, tôi đang viết một bộ phân tích với Roslyn cho C # và VB.NET, với các loại sau:

Microsoft.CodeAnalysis.CSharp.Syntax.AttributionSyntax Microsoft.CodeAnalysis.VisualBasic.Syntax.AttributionSyntax

Tôi tự hỏi liệu, bởi vì mã đang làm điều tương tự, tôi nên giữ nó càng DRY càng tốt, tách ra càng ít càng tốt thành các phương thức riêng biệt (nhưng giống hệt với loại) hoặc tách biệt hoàn toàn bởi vì hai phương thức là không liên quan và những thay đổi trong tương lai có thể buộc một phiên bản thay đổi, nhưng không phải là phiên bản khác (mặc dù điều này là không thể)?

Chỉnh sửa: Một năm sau, tôi gặp vấn đề tương tự và nhóm Roslyn đã giúp tôi giải quyết nó: Viết một lớp cơ sở lấy khái quát và có một TAttributeSyntaxtham số thực hiện hầu hết công việc. Sau đó, viết các lớp dẫn xuất với mức tối thiểu của dữ liệu cần một loại cụ thể.


Nó có hoạt động để tạo giao diện AttributionSyntax của riêng bạn bao bọc các lớp hiện có nhưng cung cấp cho bạn sự kế thừa về mặt khái niệm nên có ở đó không?
Winston Ewert

7
Xin lỗi nếu điều này là hiển nhiên, nhưng thuốc generic tồn tại để bạn không phải lặp lại chính mình cho mã giống hệt nhưng đối với loại. Nếu đó không phải là ý bạn, xin vui lòng bỏ qua.
Davislor

@Lorehead Thông thường tôi sẽ làm điều đó, nhưng đây là một phương thức duy nhất được thông qua một loại có chứa nút dưới dạng tải trọng từ một phương thức nội bộ mà tôi không kiểm soát được.
Hosch250

@WinstonEwert Tôi sẽ xem xét điều đó. Tôi không chắc chắn tôi muốn làm điều đó cho tất cả các loại C # / VB.NET.
Hosch250

1
Tái cấu trúc áp đặt nhiều thỏa hiệp và đôi khi cả nghịch lý. Ví dụ, khớp nối lỏng lẻo so với DRY, hoặc các hàm ngắn, nhưng nhiều hàm của chúng, so với các hàm dài hơn và một số ít. Cuối cùng, đó là một con thú khó khăn: Mục tiêu của bạn là khả năng đọc và bảo trì. Bạn cần nghĩ như một hình đại diện nhìn thấy mã của bạn lần đầu tiên. Và đôi khi bạn chỉ cần thử để xem những gì tốt hơn. Tái cấu trúc hoàn hảo không may là không thể.
phresnel

Câu trả lời:


111

Bạn không làm DRY bởi vì ai đó đã viết nó trong một cuốn sách ở đâu đó rằng nó tốt để làm, bạn làm DRY bởi vì nó thực sự có lợi ích hữu hình.

Cụ thể từ câu hỏi đó:

Nếu bạn lặp lại chính mình, bạn có thể tạo ra các vấn đề bảo trì. Nếu doStuff1-3 đều có mã có cấu trúc tương tự và bạn khắc phục sự cố trong một, bạn có thể dễ dàng quên khắc phục sự cố ở những nơi khác. Ngoài ra, nếu bạn phải thêm một trường hợp mới để xử lý, bạn có thể chỉ cần chuyển các tham số khác nhau vào một chức năng thay vì dán sao chép khắp nơi.

Tuy nhiên, DRY thường được đưa đến một thái cực bởi các lập trình viên thông minh. Đôi khi để không lặp lại chính mình, bạn phải tạo ra sự trừu tượng đến mức khó hiểu để đồng đội của bạn không thể theo dõi họ. Đôi khi cấu trúc của hai thứ chỉ tương tự mơ hồ nhưng đủ khác nhau. Nếu doStuff1-4 đủ khác nhau để việc tái cấu trúc chúng không lặp lại chính bạn khiến bạn phải viết mã không tự nhiên hoặc trải qua các cú nhảy mã hóa thông minh sẽ khiến nhóm của bạn lườm bạn, thì bạn có thể tự mình lặp lại. Tôi đã cúi xuống để không lặp lại một vài lần theo cách không tự nhiên và hối tiếc sản phẩm cuối cùng.

Vì vậy, về cơ bản, đừng nghĩ rằng "trời ơi, mã này khá giống nhau, có lẽ tôi nên cấu trúc lại để không lặp lại chính mình". Hãy suy nghĩ "liệu tái cấu trúc để làm cho cơ sở mã này sử dụng lại các phần tử phổ biến làm cho mã dễ bảo trì hơn hoặc ít bảo trì hơn ?" Sau đó, chọn một trong đó làm cho nó dễ bảo trì hơn.


Điều đó đã được nói, với SRP và chỉ cố gắng để có các lớp nhỏ, linh hoạt nói chung, có thể có ý nghĩa để phân tích mã của bạn vì lý do đó , tách các hành vi sử dụng các loại chung (bạn nói rằng chúng giống hệt với loại) lớp học nhỏ. Sau đó, bạn sẽ phát hiện ra rằng một số các lớp này thực sự hoàn toàn giống nhau (không chỉ giống hệt nhau), và sau đó bạn có thể xây dựng một bộ công cụ trong trường hợp bạn muốn thêm Microsoft.CodeAnalysis.CPlusPlus.Syntax.AttributeSyntax.


32
TL; DR - DRY là một phương tiện để kết thúc. Tập trung vào cuối cùng, không phải là phương tiện. Nếu tôi có thể nâng cấp Lego Man hai lần, tôi sẽ làm thế.

Một lưu ý quan trọng: nếu bạn làm lặp lại chính mình, luôn luôn đề cập đến trong các bình luận tất cả các nơi khác mà phải được truy cập khi thay đổi mã lặp đi lặp lại. Nó không chỉ làm giảm khả năng của một đồng bộ hóa, nó còn hoạt động như một chỉ báo về mức độ đau duy trì mà sự lặp lại gây ra cho bạn.
Xion
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.