Tái cấu trúc trong khi lập trình


9

Khi đặt ra một vấn đề, đặc biệt là khi nó phức tạp trong tự nhiên, tôi cố gắng dành chút thời gian để suy nghĩ về cách tiếp cận mà tôi sẽ thực hiện để giải quyết vấn đề. Mặc dù vậy, điều thường xảy ra là, khi tôi đang lập trình giải pháp, tôi bắt đầu nghĩ về các chi tiết của vấn đề mà tôi đã bỏ lỡ và tôi điều chỉnh mã cho phù hợp.

Kết quả là một mớ hỗn độn của mã cần được cấu trúc lại.

Tôi muốn "tái cấu trúc khi tôi đi", nhưng trong khi nó có vẻ dễ thực hiện, tôi có một thời gian thực sự khó khăn để làm điều đó. Khi chi tiết mà tôi bỏ lỡ là nhỏ, sẽ rất hấp dẫn khi thực hiện một bản cập nhật nhỏ cho thiết kế của tôi, thay vì xóa những gì tôi đã viết và viết nó theo cách nó được cho là như vậy.

Nghe có vẻ như một câu hỏi với một câu trả lời rõ ràng, nhưng có kỹ thuật nào để sử dụng để "tái cấu trúc khi bạn đi" tốt hơn không? Tôi biết rằng đây là một nguyên tắc tốt, nhưng tôi thất bại với nó hết lần này đến lần khác.

Câu trả lời:


17

Có lẽ quan sát cơ bản trong cuốn sách Tái cấu trúc của Fowler là bạn nên tách biệt các thay đổi ảnh hưởng đến hành vi mã với các thay đổi không tốt hơn nhiều. Những người trong loại sau, chúng tôi gọi là "tái cấu trúc". Nếu bạn trộn lẫn những thay đổi này, bạn sẽ làm hỏng chúng - vì vậy đừng. Bạn có thể chuyển đổi qua lại giữa chế độ mã hóa và tái cấu trúc, nhưng không thực hiện cả hai cùng một lúc. Bởi vì nếu bạn cố gắng, bạn sẽ không biết mình đã làm gì sai.

Nếu bạn cố gắng đưa ra một thay đổi sửa đổi hành vi và hành vi không sửa đổi: bạn đã làm gì đó sai; xem lại và sửa nó Có lẽ chỉ cần cuộn nó lại.

Nếu bạn cố gắng giới thiệu tái cấu trúc và hành vi sẽ sửa đổi: bạn đã làm sai điều gì đó; xem lại và sửa nó Có lẽ chỉ cần cuộn nó lại.

Bạn không thể thực hiện đánh giá đơn giản đó nếu bạn thử cả hai thay đổi cùng một lúc. Bạn cũng không thể, nếu bạn không có bài kiểm tra đơn vị. Viết chúng. Và làm một việc tại một thời điểm.


1
Lời khuyên thú vị ... Mặc dù, như tất cả các lời khuyên, không phải 100%. Tôi nghĩ lời khuyên này hoạt động tốt nếu bạn thực hiện tái cấu trúc tương đối nhỏ một mã lớn. Nhưng đôi khi các phép tái cấu trúc thực sự triệt để, như viết lại gần như hoàn chỉnh, cũng đi kèm với các tính năng hoàn toàn mới - và hiệu quả là thực hiện cả hai cùng một lúc.
Tomas

3
@Tomas: Câu hỏi rõ ràng là về "tái cấu trúc khi bạn đi", cũng như câu trả lời của Carl (+1 từ tôi). Một "viết lại gần như hoàn chỉnh" không tái cấu trúc ... đó là, viết lại.
Amos M. Carpenter

1
Không chỉ trộn mã hóa với tái cấu trúc sẽ làm mọi thứ rối tung lên, mà còn thực hiện tái cấu trúc khác nhau cùng một lúc .
Rangi Lin

6

Đây là những gì tôi thường làm: để lại cho bạn ghi chú dưới dạng nhận xét hoặc thậm chí mã nhận xét. Khi bạn đã có mã cẩu thả hoạt động, bây giờ bạn có thể tổ chức lại mã dễ dàng.

Ngoài ra, không có gì sai khi tái cấu trúc khi bạn đi, chỉ cần đảm bảo rằng bạn có cách để kiểm tra xem mã tái cấu trúc của bạn không đưa ra các lỗi mới trước khi bạn tiến hành.


đã đồng ý. Thường dễ dàng tinh chỉnh mã làm việc xấu xí thành mã đẹp hơn là cố gắng làm lại từ đầu. Bạn chỉ cần trung thực và cho mình thời gian để làm sạch giải pháp của bạn một khi nó đang hoạt động.
bunglestink

2
Cảnh giác với việc để lại quá nhiều mã nhận xét, nếu không nó sẽ làm lộn xộn mọi thứ. Nói chung nếu bạn đã thay thế mã xấu, bạn chỉ nên xóa nó. Ngoài ra, nếu đó là một dự án nhóm, các lập trình viên đồng nghiệp của bạn thường không thích bạn vì đã cam kết mã nhận xét mà không có lý do tuyệt vời.
user24795

1
Cách tiếp cận của tôi: nếu bạn không chắc chắn về những gì bạn đang làm, hãy nhận xét mã cũ. Bao gồm tên viết tắt của bạn và ngày . Nếu bạn bắt gặp những thứ dường như không còn phù hợp với ngày cũ, hãy xóa nó, đặc biệt nếu nó có tên viết tắt của bạn trên đó. Nếu bạn kích hoạt lại mã cũ và không biết lý do tại sao nó bị vô hiệu hóa, hãy thêm một lời giải thích kỹ lưỡng để sau đó ai đó (có lẽ bạn) muốn đưa nó trở lại như cũ, bạn sẽ biết bạn đang ở trong một vòng lặp phát triển vô hạn biết làm thế nào để thoát khỏi nó
RalphChapin

5

Một quy tắc tốt khác là mọi phương pháp chỉ nên làm một việc.

Nếu bạn chia nhỏ việc xử lý những gì bạn đang cố gắng thực hiện thành các bước nhỏ lẻ và mã hóa các bước thành phương thức, thì khi đến lúc phải tính lại, bạn sẽ thấy rằng việc tái cấu trúc duy nhất có ý nghĩa là thay đổi để các phương thức được gọi trong hoặc để một số phương thức ra khỏi đường dẫn thực thi.

Ngoài ra, vì các phương thức của bạn là rời rạc, bạn có thể tự do tính lại bất kỳ phương thức đơn lẻ nào miễn là giá trị được trả về là đúng, không có mã nào khác sẽ là bất kỳ sự thay đổi nào được thực hiện.

Điều này đặt ra giai đoạn để bạn thực hiện các cải tiến gia tăng cho mã của mình theo thời gian bằng cách tối ưu hóa một phương thức ở đây và đó. Logic tổng thể không thay đổi, chỉ là chi tiết của một bước cụ thể.

Nếu bạn theo dõi điều này từ các phương thức đến các lớp, trong đó trong các lớp của bạn chỉ hoặc đại diện cho một đối tượng duy nhất, bạn sẽ thấy rằng, giống như với các phương thức, phép tái cấu trúc của bạn trở nên giống như sắp xếp lại thứ tự mà các lớp của bạn được xây dựng và sử dụng , và ít hơn về việc thực sự thay đổi logic chi tiết.

Bạn biết rằng bạn đã đạt được điểm cao khi đặc tả chương trình thay đổi mạnh mẽ và đột ngột, nhưng bạn có thể điều chỉnh gần như tất cả các thay đổi cần thiết chỉ bằng cách sửa đổi mối quan hệ giữa các đối tượng của bạn - mà không thay đổi việc thực hiện bên trong của chúng! Cảm giác như bạn đột nhiên có được niết bàn!

Chúc may mắn và có thể tất cả mã của bạn không có lỗi!

Rodney



2

Có thể bạn đang viết các giao diện như thể thực hiện một cách tiếp cận từ trên xuống để giải quyết vấn đề, nhưng sau đó thực hiện từ dưới lên? Nếu vậy thì tôi nghĩ đó là sự không phù hợp logic đang gây ra vấn đề cho bạn.

Dựa trên những gì bạn mô tả, có thể tốt hơn để phá vỡ vấn đề để bạn có thể nghĩ ra ít nhất một điều bạn cần làm, sau đó thực hiện điều đó. Hãy nghĩ về một điều khác bạn cần làm và thực hiện điều đó. Tiếp tục, xây dựng giải pháp của bạn để bạn viết các nguyên tắc cơ bản tuyệt đối trước, sau đó các khối xây dựng nằm trên đầu chúng và tiếp tục đi lên cho đến khi bạn có giải pháp thực tế đóng đinh. Tôi có xu hướng thấy rằng giải pháp hoàn chỉnh, ngay cả đối với các vấn đề khó khăn, có xu hướng lẻn vào bạn và đột nhiên nhảy ra khi làm theo cách tiếp cận đó.

Nếu bạn giữ các khối xây dựng trung gian tập trung một cách hợp lý và cố tình giữ cho mỗi phân đoạn mã được đóng và giới hạn thì số lượng tái cấu trúc bạn sẽ cần phải luôn luôn nhỏ và tách biệt.


Đây là những gì tôi đang làm, tôi nghĩ. Tôi thường viết phác thảo về những gì tôi muốn làm - ví dụ như trong mẫu thiết kế phương thức mẫu. Sau đó, tôi thực hiện các phương pháp đó. Khi tôi đi vào chi tiết, đôi khi tôi phát hiện ra điều gì đó không đúng trong mẫu ban đầu.
Kirby

1

... Thật là hấp dẫn khi thực hiện một bản cập nhật nhỏ cho thiết kế của tôi, thay vì xóa những gì tôi đã viết và viết nó theo cách nó được yêu cầu .

Không có gì được cho là. Điều duy nhất được cho là:

  1. bạn có thể làm bất cứ điều gì bạn muốn
  2. thời gian sống / thời gian làm việc của bạn bị giới hạn và bạn chỉ có thể đạt được một số thứ giới hạn.

Bạn muốn gì? Một dự án hoàn thành siêu lừa đảo hoàn hảo-xuất sắc-mã-sạch, hoặc ba dự án đã hoàn thành, chỉ bằng 70%-độ thanh lịch so với trước đây, nhưng gấp 3% 95% so với quan điểm của người dùng? Điều gì sẽ hữu ích hơn cho thế giới, cho nhân dân của bạn, cho nhiệm vụ của bạn?

Bạn muốn gì?

Tất nhiên, về lâu dài, nó có thể trả hết cho tái cấu trúc (giảm thời gian mtce, v.v.), nhưng chỉ trong thời gian dài. Chúng tôi, các lập trình viên, thường bị cám dỗ để cấu trúc lại và tối ưu hóa sớm hơn nhiều so với mức cần thiết. Chúng tôi thường cấu trúc lại một mã không được phát triển thêm, điều đó có nghĩa là lãng phí thời gian.

Tôi sử dụng quy tắc vàng 2-3 của riêng tôi. Trong lần sử dụng đầu tiên của mã cụ thể, tôi chỉ bastle nó càng sớm càng tốt. Hầu như không bao giờ trả hết khi nghĩ về việc sử dụng chung hơn, bởi vì bạn chưa có đủ thông tin về những trường hợp sử dụng có thể xảy ra. Ngoài ra, phần mã này có thể không bao giờ được sử dụng lại. Khi cần mã lần thứ hai, tôi cố gắng làm cho mã đầu tiên chung chung hơn để áp dụng cho trường hợp này hoặc tôi chọn sao chép mã (nhưng điều này tôi không thích). Với cách sử dụng thứ 3, tôi cảm thấy mình có đủ thông tin để cấu trúc lại và, vì phần mã này dường như thực sự được sử dụng, tôi cảm thấy nó được đền đáp.


0

Kết quả là một mớ hỗn độn của mã cần được cấu trúc lại.

Chỉ cần thổi qua vấn đề cho đến khi bạn hiểu nó. Sau đó thực hiện mới, thực hiện chính xác sau khi bạn biết hình thức của nó.

Để trả lời câu hỏi của bạn bằng những thuật ngữ chung chung hơn: Nhắc nhở bản thân rằng những thay đổi cần thiết thường gây ra ít gợn / thử lại nếu được thực hiện sớm hơn sau đó.

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.