Làm thế nào để loại bỏ mã trùng lặp (nói chung)?


10

Trong ngôn ngữ OO (ví dụ: nhưng không giới hạn ở Java), làm thế nào để bạn sửa mã trùng lặp tùy thuộc vào phạm vi xảy ra của nó? Tôi sẽ bắt đầu với (ví dụ)

  • trong cùng một lớp (phạm vi) thực hiện tái cấu trúc Phương thức trích xuất (sửa chữa)
  • trong các lớp có cùng phân cấp (phạm vi) thực hiện Phương thức trích xuất và Kéo lên (sửa)
  • ...

có một cái nhìn tại một ví dụ cho việc thực hiện nguyên tắc DRY (Đừng lặp lại chính mình) với cùng một lớp ở đây: geekswithblogs.net/chrisfalter/archive/2008/03/07/...
NoChance

Câu hỏi ban đầu tại SO ( stackoverflow.com/questions/7380946/ săn ) đã bị đóng. Vì vậy, tôi đã chuyển nó ở đây.
Peter Kofler

Câu trả lời:


8

Gần đây tôi đã tìm thấy một câu trả lời hay cho câu hỏi của tôi trong cuốn "Mã sạch" của chú Bob, mà tôi muốn chia sẻ. Ông phân biệt ba loại trùng lặp

Các đoạn mã giống hệt nhau nên được thay thế bằng một phương thức duy nhất. Vì vậy, sửa chữa sẽ là trích xuất phương thức và ủy thác cho hành vi phổ biến.

  • trong cùng một phương thức, thực hiện Trích xuất biến cục bộ và sử dụng lại nó.
  • trong cùng một lớp thực hiện tái cấu trúc Phương thức trích xuất.
  • trong các lớp của cùng một phương thức trích xuất phân cấp và kéo nó lên. Một hệ thống phân cấp có thể được tạo để tìm một vị trí cho các phương thức.
  • trong các lớp của hệ thống phân cấp riêng biệt sử dụng ủy quyền cho các đối tượng mới.
  • Nếu các phương thức không cần bất kỳ trạng thái kèm theo nào, thì mẫu "lib" có thể được áp dụng (đó là một thùng chứa cho các phương thức tĩnh, thường được gọi là SthUtilhoặc SthLib).

trường hợp switch/caseif/elseluôn luôn kiểm tra cho cùng một tập hợp các điều kiện .

  • Chúng nên được thay thế bằng đa hình.

Các mô-đun thực hiện các thuật toán tương tự . Đây là những thứ khó tìm nhất, vì không có máy dò nhân bản nào có thể tìm thấy chúng.

  • Khi phạm vi là patters thiết kế lớn hơn được sử dụng. Mẫu thiết kế Phương thức mẫu có thể được áp dụng cho các thuật toán bên trong hệ thống phân cấp lớp.
  • Mẫu thiết kế chiến lược có thể được áp dụng cho bất kỳ thuật toán nào được sử dụng ở những nơi khác nhau.

Cũng là một điểm hợp lệ được đề cập bởi Oded, khi giao dịch với các phiên bản khác nhau của thư viện

  • hợp nhất trên một phiên bản duy nhất. Mẫu thiết kế mặt tiền có thể giúp ở đây.

Cuối cùng, một câu tốt nhất để trả lời câu hỏi của tôi là bởi sự kích thích:

phương pháp tái sử dụng mã được sử dụng trong các ngôn ngữ OO là các đối tượng.


5

Nói chung - hợp nhất mã trùng lặp vào một nơi duy nhất và đảm bảo trang web trùng lặp ban đầu đang gọi địa điểm hợp nhất.

Trong các ví dụ của bạn, trong một lớp, đây sẽ là phương thức được trích xuất và trong một tập hợp các lớp, phương thức kéo lên trong lớp cơ sở.

Trong mã sao chép-dán, điều này sẽ là loại bỏ các bản sao và đảm bảo rằng bất kỳ người dùng nào hiện nay đều sử dụng bản sao duy nhất (dù ở cấp độ nào).

Khi giao dịch với các phiên bản khác nhau của thư viện, hợp nhất trên một phiên bản duy nhất (nếu có thể).


Nó sẽ không phải là phương thức "kéo xuống" nếu nó ở trong một lớp cơ sở? Tôi luôn tưởng tượng các lớp cơ sở là vật lý dưới các lớp dẫn xuất.
Dave Nay

Tên thích hợp từ cuốn sách Tái cấu trúc là "kéo lên".
Peter Kofler

1

Tôi đoán đây là một câu hỏi kết thúc mở nhưng nó cũng phụ thuộc vào trạng thái của mã. Ý tôi là bạn có thể chấp nhận mã trùng lặp một chút tùy thuộc vào ngữ cảnh. Quy tắc ba là tốt cho vấn đề này.

Rule Of Three Lần đầu tiên bạn làm một cái gì đó, bạn chỉ cần làm nó. Lần thứ hai bạn làm điều gì đó tương tự, bạn nhăn nhó với sự trùng lặp, nhưng dù sao bạn cũng làm điều trùng lặp. Lần thứ ba bạn làm một cái gì đó tương tự, bạn tái cấu trúc.

Mặc dù điều này là khá nhiều tranh cãi, bài đăng này cũng xem xét các trường hợp bạn sẽ chấp nhận mã trùng lặp.


1
+1 về "quy tắc ba". Tôi luôn luôn ngạc nhiên về cách áp dụng rộng rãi.
andy xoài

1
Điều này không trả lời câu hỏi như thế nào .
Jan Doggen
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.