2010-09-23 18 views
7

Khi tôi nhận được mã tôi chưa thấy trước đó để cấu trúc lại thành trạng thái sane, tôi thường sửa chữa các thứ "mỹ phẩm" (như chuyển đổi StringTokenizers thành String#split(), thay thế bộ sưu tập trước 1,2 bộ sưu tập mới hơn, tạo trường final, chuyển đổi kiểu C mảng thành các mảng kiểu Java, ...) trong khi đọc mã nguồn tôi phải làm quen với."Mỹ phẩm" làm sạch mã cũ, không xác định. Bước nào, thứ tự nào? Làm thế nào xâm lấn?

Có nhiều người sử dụng chiến lược này không? ? Hoặc là nó phổ biến hơn để kết hợp các bước "làm sạch mỹ phẩm" với bước "tái cấu trúc tổng hợp" xâm lấn hơn?

"Trái cây treo thấp" phổ biến là gì khi thực hiện "làm sạch mỹ phẩm" (so với tái cấu trúc với nhiều thay đổi xâm lấn)?

+1

Đối với những gì đáng giá tôi thực sự yêu cuốn sách Tái cấu trúc của Martin Fowler: http://martinfowler.com/books.html#refactoringRubyEd –

Trả lời

7

Theo ý kiến ​​của tôi, "làm sạch mỹ phẩm" "tái cấu trúc chung". Bạn chỉ cần thay đổi mã để làm cho nó dễ hiểu hơn mà không thay đổi hành vi của nó.

Tôi luôn luôn cấu trúc lại bằng cách tấn công các thay đổi nhỏ trước. Bạn càng dễ đọc mã, bạn càng dễ dàng thực hiện các thay đổi về cấu trúc sau này - đặc biệt vì nó giúp bạn tìm kiếm mã lặp lại, v.v.

Tôi thường bắt đầu bằng cách xem mã được sử dụng thường xuyên và sẽ cần phải được thay đổi thường xuyên, đầu tiên. Biến đổi tên có lẽ là "quả treo thấp" dễ nhất và an toàn nhất để tấn công trước, theo sau là các cập nhật khung (thay đổi bộ sưu tập, phương thức cập nhật, v.v.). Một khi chúng được thực hiện, phá vỡ các phương thức lớn thường là bước tiếp theo của tôi, tiếp theo là các phép tái cấu trúc điển hình khác.

2

Điều đầu tiên tôi làm là cố gắng che giấu hầu hết mọi thứ với thế giới bên ngoài. Nếu mã là crappy hầu hết thời gian anh chàng mà thực hiện nó không biết nhiều về ẩn dữ liệu và như nhau.

Vì vậy, lời khuyên của tôi, điều đầu tiên cần làm:

Bật càng nhiều thành viên và các phương pháp như tin như bạn có thể mà không vi phạm các biên dịch.

Bước thứ hai tôi cố gắng xác định giao diện. Tôi thay thế các lớp cụ thể thông qua các giao diện trong tất cả các phương thức của các lớp liên quan. Bằng cách này bạn phân tách các lớp một chút.

Việc tái cấu trúc thêm sau đó có thể được thực hiện an toàn hơn và cục bộ hơn.

2

Bạn có thể mua bản sao Refactoring: Improving the Design of Existing Code từ Martin Fowler, bạn sẽ tìm thấy rất nhiều thứ bạn có thể làm trong quá trình tái cấu trúc.

Ngoài ra, bạn có thể sử dụng các công cụ được cung cấp bởi IDE và các trình phân tích mã khác như Findbugs hoặc PMD để phát hiện sự cố trong mã của bạn.


Resources:

Trên cùng một chủ đề:

+0

Có, tốt hơn nhiều để * cũng * chạy mã của bạn thông qua các công cụ như FindBugs, PMD, v.v. – ssahmed555

1

Tôi thường không bận tâm đi qua mã cũ tìm kiếm các vấn đề. Tuy nhiên, nếu tôi đọc nó, dường như bạn đang làm, và nó làm cho bộ não của tôi bị trục trặc, tôi sửa nó.

Các loại hoa quả treo thường gặp cho tôi có xu hướng đổi tên lớp, phương pháp, trường, v.v ... và viết các ví dụ về hành vi (kiểm tra đơn vị) khi tôi không chắc chắn - thường làm cho mã dễ đọc hơn khi tôi đọc nó. Không ai trong số này là những gì tôi gọi là "xâm lấn" nhưng chúng không chỉ là mỹ phẩm.

2

Bạn đang đi đúng hướng. Bằng cách thực hiện các bản sửa lỗi nhỏ, bạn sẽ quen thuộc hơn với mã và các bản sửa lỗi lớn hơn sẽ dễ dàng hơn với tất cả các mảnh vụn trên đường đi.

Chạy công cụ như JDepend, CheckStyle hoặc PMD trên nguồn. Họ có thể tự động thực hiện vô số thay đổi có tính đồng phân nhưng dựa trên các quy tắc tái cấu trúc chung.

4

Không có câu trả lời đúng hay sai ở đây, vì điều này phụ thuộc phần lớn vào hoàn cảnh.

Nếu mã đang hoạt động, đang hoạt động, không có giấy tờ và không chứa cơ sở hạ tầng kiểm tra thì tôi sẽ không chạm vào. Nếu ai đó quay trở lại trong tương lai và muốn có các tính năng mới, tôi sẽ cố gắng làm việc với chúng trong mã hiện có trong khi thay đổi ít nhất có thể.

Nếu mã bị lỗi, có vấn đề, thiếu tính năng và được viết bởi một lập trình viên không còn làm việc với công ty nữa, tôi có thể thiết kế lại và viết lại toàn bộ. Tôi luôn có thể tham khảo mã của lập trình viên cho một giải pháp cụ thể cho một vấn đề cụ thể, nhưng nó sẽ giúp tôi tổ chức lại mọi thứ trong tâm trí và trong nguồn. Trong tình huống này, toàn bộ điều có lẽ được thiết kế kém và nó có thể sử dụng một suy nghĩ lại hoàn toàn.

Đối với tất cả mọi thứ ở giữa, tôi sẽ thực hiện phương pháp bạn phác thảo. Tôi sẽ bắt đầu bằng cách làm sạch mọi thứ một cách thẩm mỹ để tôi có thể thấy những gì đang xảy ra. Sau đó, tôi bắt đầu làm việc trên bất kỳ mã nào nổi bật khi cần nhiều công việc nhất. Tôi sẽ thêm tài liệu khi tôi hiểu cách nó hoạt động để tôi sẽ giúp nhớ những gì đang xảy ra.

Cuối cùng, hãy nhớ rằng nếu bạn sẽ duy trì mã ngay bây giờ, nó phải phù hợp với tiêu chuẩn của bạn. Nơi nó không phải, bạn nên dành thời gian để mang nó lên đến tiêu chuẩn của bạn - bất cứ điều gì mà mất. Điều này sẽ giúp bạn tiết kiệm rất nhiều thời gian, công sức và thất vọng trên con đường.

+0

+1 để thoát khỏi mã độc lập trừ khi chức năng bị hỏng hoặc yêu cầu tính năng mới. Tôi đã nhìn thấy rất nhiều thời gian lãng phí mỹ phẩm khi có một tồn đọng của các vấn đề thực sự để giải quyết. –

+0

+1 cho _Nếu mã đang hoạt động, ..._ –

2

Bằng cách bắt đầu với "dọn dẹp mỹ phẩm", bạn sẽ có được cái nhìn tổng quan về mã lộn xộn như thế nào và điều này kết hợp với khả năng đọc tốt hơn là một khởi đầu tốt.

Tôi luôn luôn (vâng, phải ... đôi khi có điều gì đó gọi là hạn chót gây rối với tôi) bắt đầu với cách tiếp cận này và nó đã phục vụ tôi rất tốt cho đến nay.

2

Tôi không thay đổi mã cũ ngoại trừ định dạng lại mã bằng IDE. Có quá nhiều rủi ro khi đưa ra lỗi - hoặc xóa một lỗi mà mã khác hiện phụ thuộc vào! Hoặc giới thiệu một sự phụ thuộc không tồn tại như sử dụng đống thay vì ngăn xếp.

Ngoài định dạng IDE, tôi không thay đổi mã mà sếp đã không yêu cầu tôi thay đổi. Nếu có điều gì đó là nghiêm trọng, tôi hỏi ông chủ xem tôi có thể thực hiện thay đổi hay không và nêu rõ lý do tại sao điều này là tốt cho công ty.

Nếu sếp yêu cầu tôi sửa lỗi trong mã, tôi thực hiện càng ít thay đổi càng tốt. Nói lỗi là một vòng lặp đơn giản. Tôi muốn cấu trúc lại vòng lặp thành một phương thức mới. Sau đó, tôi sẽ viết một trường hợp thử nghiệm cho phương pháp đó để chứng minh tôi đã đặt lỗi. Sau đó, tôi sẽ sửa chữa phương pháp mới. Sau đó, tôi chắc chắn rằng các trường hợp kiểm tra đã qua.

Vâng, tôi là nhà thầu. Ký kết cung cấp cho bạn một quan điểm khác. Tôi khuyến khích điều đó.

1

Từ kinh nghiệm nó phụ thuộc vào hai điều: thời gian và rủi ro.

Nếu bạn có nhiều thời gian thì bạn có thể làm nhiều hơn, nếu không thì phạm vi của bất kỳ thay đổi nào bạn thực hiện sẽ giảm tương ứng. Nhiều như tôi ghét làm điều đó tôi đã phải tạo ra một số hacks đáng xấu hổ khủng khiếp bởi vì tôi chỉ đơn giản là không có đủ thời gian để làm điều đó ...

Nếu mã bạn đang làm việc có rất nhiều phụ thuộc hoặc quan trọng cho các ứng dụng sau đó làm cho càng ít thay đổi càng tốt - bạn không bao giờ biết những gì bạn sửa chữa có thể phá vỡ ... :)

có vẻ như bạn có một ý tưởng vững chắc của những điều nên trông giống như vì vậy tôi không phải là sẽ nói những thay đổi cụ thể nào được thực hiện theo thứ tự nào sẽ gây ra thay đổi từ người này sang người khác. Chỉ cần thực hiện các thay đổi cục bộ nhỏ trước, thử nghiệm, mở rộng phạm vi thay đổi, kiểm tra của bạn. Mở rộng. Kiểm tra. Mở rộng. Kiểm tra. Cho đến khi bạn hết thời gian hoặc không còn chỗ để cải thiện!

BTW Khi thử nghiệm, bạn có thể thấy nơi mọi thứ xảy ra thường xuyên nhất - tạo các trường hợp thử nghiệm cho chúng (JUnit hoặc bất kỳ thứ gì).

EXCEPTION: Hai điều tôi luôn thấy mình đang thực hiện là định dạng lại (CTRL + SHFT + F trong Eclipse) và mã nhận xét không rõ ràng. Sau đó tôi chỉ cần đóng đinh rõ ràng nhất trước tiên ...

3

Trái cây mỹ phẩm treo thấp nhất là (trong Eclipse, anyway) shift-control-F. Định dạng tự động là bạn của bạn.

2

Có một điều bạn nên biết. Mã bạn đang bắt đầu bằng đã được KIỂM TRA và được chấp thuận và các thay đổi của bạn tự động có nghĩa là việc kiểm tra lại phải xảy ra vì bạn có thể vô tình làm hỏng một số hành vi ở nơi khác.

Bên cạnh đó, mọi người đều mắc lỗi. Mỗi thay đổi không tầm thường bạn thực hiện (thay đổi StringTokenizer thành split là không phải là một tính năng tự động trong ví dụ Eclipse, do đó bạn tự viết nó) là một cơ hội cho các lỗi xảy ra. bạn có nhầm lẫn khi quên một số ! không?

Do đó, các thay đổi của bạn ngụ ý kiểm tra lại. Công việc đó có thể khá đáng kể và bị áp đảo nghiêm trọng những thay đổi nhỏ mà bạn đã thực hiện.

Các vấn đề liên quan