Trong một cơ sở mã di sản, làm thế nào để tôi nhanh chóng tìm ra cái gì đang được sử dụng và cái gì không?


21

Tôi đã được yêu cầu đánh giá những gì dường như là một cơ sở mã di sản đáng kể, như một tiền thân để thực hiện một hợp đồng duy trì cơ sở mã đó.

Đây không phải là lần đầu tiên tôi gặp tình huống này. Trong trường hợp hiện tại, mã dành cho một trang web chơi game nhiều người chơi có cấu hình khá cao và khá tải, hỗ trợ ít nhất vài nghìn người chơi trực tuyến cùng một lúc. Như nhiều trang web như vậy, trang này là sự kết hợp của các công nghệ mặt trước và mặt sau.

Cấu trúc trang web nhìn từ trong ra ngoài, là một mớ hỗn độn. Có các thư mục có hậu tố "_OLD" và "_DELETE" nằm khắp nơi. Nhiều thư mục dường như không phục vụ mục đích hoặc có tên rất khó hiểu. Có thể có bất kỳ số lượng các tập lệnh cũ, chưa sử dụng nằm xung quanh ngay cả trong các thư mục trông hợp pháp. Không chỉ vậy, nhưng chắc chắn có nhiều phần mã không còn tồn tại ngay cả trong các tập lệnh hoạt động khác (một mối quan tâm ít gây bức xúc hơn).

Đây là một bàn giao từ các nhà bảo trì đương nhiệm, trở lại các nhà phát triển / bảo trì ban đầu của trang web. Như một điển hình dễ hiểu trong các loại kịch bản này, đương nhiệm không muốn làm gì với việc bàn giao ngoài những gì được yêu cầu về mặt hợp đồng và pháp lý của họ để đẩy nó ra cho người bảo trì mới được bầu. Vì vậy, trích xuất thông tin về cấu trúc trang web hiện tại ra khỏi đương nhiệm chỉ đơn giản là không cần thiết.

Cách tiếp cận duy nhất xuất hiện trong codebase là bắt đầu từ trang gốc và từ từ nhưng chắc chắn điều hướng qua các tập lệnh được liên kết ... và có thể có hàng trăm sử dụng, và hàng trăm thứ khác thì không. Do một phần đáng kể của trang web là trong Flash, điều này thậm chí còn đơn giản hơn, đặc biệt là trong các ứng dụng Flash cũ hơn, các liên kết đến các tập lệnh khác có thể được nhúng trong tệp nhị phân (.Ls) thay vì trong tệp văn bản (.AS / ActionScript).

Vì vậy, tôi tự hỏi nếu có ai có đề xuất tốt hơn về cách tiếp cận đánh giá codebase một cách tổng thể để duy trì. Thật tuyệt vời nếu có một cách nào đó để xem biểu đồ tần suất truy cập vào các tệp trên HĐH của máy chủ web (mà tôi có quyền truy cập), vì điều này có thể cung cấp một số thông tin chi tiết về các tệp quan trọng nhất, mặc dù nó sẽ không có thể loại bỏ những tệp không bao giờ được sử dụng (vì một số tệp có thể được sử dụng chỉ một lần một năm).


7
Tôi không biết đủ về flash nhưng nếu bạn gặp lỗi biên dịch khi không có mã, bạn có thể đổi tên các thư mục để xem chúng có được tham chiếu không.
Oded

Giải pháp độc ác: Xóa chúng và chờ báo cáo lỗi / lỗi. (Chỉ cần đảm bảo rằng nó có thể phục hồi!)
Izkata

1
@Nick Bạn có thể làm rõ nếu bạn được trả tiền cho việc đánh giá như là một phần của giai đoạn hợp đồng tiếp theo mà bạn vẫn phải trả giá trên / nếu không thì có được không? Câu trả lời của bạn sẽ không thay đổi câu hỏi "có công cụ nào không", nhưng một số người trong chúng tôi có thể đưa ra câu trả lời lại: quy trình phù hợp hơn với tình huống của bạn (ví dụ: giữ cho bạn không bị vặn vẹo, v.v.).
jcmeloni

@jcmeloni Không, tôi không được trả tiền để đánh giá. Nhưng theo kinh nghiệm của tôi , và từ những điều nhỏ nhặt mà tôi đã nhặt được trong vài ngày qua, họ không có ai khác ở bàn ngay bây giờ. Kỹ năng của tôi khá bất thường, vì vậy tôi thậm chí còn thoải mái hơn khi họ không có ai khác cạnh tranh vì nó, dựa trên trích dẫn. Báo giá thực tế trong câu hỏi là từ khách hàng của tôi đến khách hàng của họ, người đang có kế hoạch trao lại cho họ hợp đồng. Thực sự từ cuối của tôi, tôi có nghĩa là để hỗ trợ họ trong việc cung cấp trích dẫn nói. HTH.
Kỹ sư

@Oded Đổi tên chắc chắn dễ dàng hơn xóa thử và lỗi! Suy nghĩ tốt đấy. Đó là một công cụ nữa trong hộp.
Kỹ sư

Câu trả lời:


32

Vì những gì bạn được yêu cầu là cung cấp đầu vào cho khách hàng của bạn để viết một đề xuất phù hợp cho khách hàng khác (chủ sở hữu mã ác mộng) cho bất kỳ công việc nào về mã đó, tôi sẽ tiếp tục một chi và nói rằng bạn sẽ không thực hiện bất kỳ thử nghiệm hoặc tái cấu trúc kỹ lưỡng hoặc bất cứ điều gì dọc theo những dòng đó vào thời điểm này. Bạn có thể có một thời gian rất ngắn để có được một ước tính sơ bộ. Câu trả lời của tôi dựa trên kinh nghiệm của tôi trong tình huống tương tự, và vì vậy nếu cách giải thích của tôi không chính xác, chỉ cần bỏ qua mọi thứ tiếp theo.

  • Sử dụng một công cụ spidering để hiểu được những trang nào ở đó và những gì được gửi đến. Ngay cả một công cụ kiểm tra liên kết cơ bản - không phải là một công cụ "nhện cho mục đích kiểm toán" cụ thể - sẽ hữu ích trong vấn đề này.
  • Lập bảng tính kiểm toán / kiểm kê cơ bản. Điều này có thể đơn giản như một danh sách các tệp và thời gian sửa đổi lần cuối của chúng, được sắp xếp theo thư mục. Điều này sẽ giúp bạn hiểu được phạm vi và khi bạn đến các thư mục như _OLD và _DELETE, bạn có thể lưu ý rằng a) đánh giá của bạn dựa trên nội dung không có trong các thư mục đó b) sự hiện diện của các thư mục đó và tiềm năng cho Bằng cách nào đó, những cơn ác mộng ẩn giấu chứng thực cho những vấn đề sâu sắc hơn cần được tính đến trong giá thầu của khách hàng của bạn , theo một cách nào đó. Bạn không cần phải mất một năm để liệt kê các vấn đề có thể xảy ra trong _OLD hoặc _DELETE; thông tin sẽ được đưa vào giá thầu cuối cùng.
  • Cho rằng bạn đang xem xét những gì nghe giống như một ứng dụng hoàn toàn dựa trên web, ngay cả các công cụ phân tích nhật ký tiêu chuẩn cũng sẽ là bạn của bạn. Bạn sẽ có thể thêm vào bảng tính một số ý nghĩa của "điều này nằm trong top 10 của các tập lệnh truy cập" hoặc một số như vậy. Ngay cả khi các tập lệnh được nhúng trong các tệp Flash và do đó không thể truy cập được, có khả năng cao chúng được truy cập thông qua POST hoặc GET và sẽ hiển thị trong nhật ký máy chủ. Nếu bạn biết bạn có 10 tập lệnh được truy cập cao, chứ không phải 100 (hoặc ngược lại), điều này sẽ cho bạn ý tưởng tốt về cách công việc bảo trì có thể sẽ diễn ra.

Ngay cả trong một trang web phức tạp, những gì tôi đã nêu ở trên là những gì bạn có thể làm trong một ngày hoặc một ngày rưỡi. Vì câu trả lời bạn sẽ đưa ra cho khách hàng của mình là đại loại như "đây sẽ là một nỗi đau rất lớn ở mông, và đây là một số lý do tại sao bạn sẽ đặt son môi lên heo, vì vậy bạn nên trả giá phù hợp "hoặc" bất kỳ người hợp lý nào sẽ trả giá không phải duy trì mà là bắt đầu lại, vì vậy bạn nên đặt giá thầu phù hợp "hoặc thậm chí" điều này không tệ, nhưng nó sẽ là một dòng công việc nhất quán trong bất kỳ khung thời gian nhất định nào, vì vậy hãy đặt giá thầu phù hợp " , vấn đề là họ sẽ thực hiện đấu thầu và do đó bạn không cần phải chính xác như bạn sẽ được thuê trực tiếp để thực hiện kiểm toán kiến ​​trúc và nội dung đầy đủ.


2
+1 Đây là một câu trả lời tuyệt vời. Nút +5 đó ở đâu ...
Kỹ sư

1
TL; DR: đừng gửi mình xuống hố thỏ cho đến khi bạn phải. :)
jcmeloni

4

Tôi thực sự khuyên bạn nên tái cấu trúc mã nguồn hiện tại (trái ngược với viết lại) bằng cách sử dụng các mẫu được tìm thấy trong cuốn sách " Làm việc hiệu quả với mã kế thừa ".

Cuốn sách chi tiết một số cơ chế để bao quát hiệu quả mã kế thừa trong các thử nghiệm đơn vị, để sau đó bạn có thể bắt đầu cấu trúc lại mã một cách an toàn. Cuốn sách bị vỡ thành nhiều phần, một phần mô tả triết lý đằng sau cách tiếp cận, và sau đó một vài chương giải quyết các vấn đề cụ thể, chẳng hạn như "Phải mất mãi mãi để thay đổi", "Tôi không có nhiều thời gian và cần thay đổi nó" và "Tôi không thể đưa lớp này vào khai thác thử nghiệm". Mỗi chương này có các kỹ thuật chi tiết, đã được chứng minh giúp bạn tìm hiểu cách áp dụng các thực tiễn tốt nhất trong thử nghiệm cho các vấn đề trong thế giới thực.

Đọc cuốn sách để lại cho tôi một cảm giác rất thực tế rằng "chúng tôi không đơn độc" ... nhiều người trong chúng tôi, hoặc có lẽ tất cả chúng tôi, đang làm việc với các cơ sở mã phức tạp đã trở nên khó quản lý. Các kỹ thuật được liệt kê trong cuốn sách đã mang lại cho tôi nhiều hy vọng và cá nhân tôi đã có thể áp dụng chúng gần như ngay lập tức.

Bài đăng trên blog của Joel Spolsky thực hiện một công việc tuyệt vời để giải thích lý do tại sao tốt nhất là giữ một cơ sở mã làm việc hiện có, trái ngược với bắt đầu từ đầu. Tôi đã chọn một trích dẫn từ bài báo tổng hợp nó, nhưng nó là một bài đọc tuyệt vời.

"Có một lý do tinh tế mà các lập trình viên luôn muốn vứt bỏ mã và bắt đầu lại. Lý do là họ nghĩ rằng mã cũ là một mớ hỗn độn. Và đây là một quan sát thú vị: có lẽ họ đã sai. mã là một mớ hỗn độn là do một quy tắc cơ bản, cơ bản của lập trình:

Đọc mã khó hơn viết mã. ". - http://www.joelonsoftware.com/articles/fog0000000069.html


4
+1. Đáp lại bình luận của Joel, "Không nên đẫm máu." Bởi vì tôi không thấy vấn đề là cố hữu. Tôi thấy đó là một phần thực tế là nhiều người viết mã kém chất lượng và không quan tâm, trong khi nhiều người khác viết mã hợp lý nhưng sống theo khái niệm "mã tự ghi" ... chỉ đơn giản là BS: Người ta có thể tâng bốc Phong cách mã hóa của riêng ai đó tất cả mọi người đều mong muốn trong sự riêng tư, nhưng khi nói đến các cơ sở mã hóa công cộng, chỉ cần sinh ra các bình luận như không có ngày mai. Không đau. Và cuối cùng, có những người phải làm cho mọi thứ hoạt động trong một cơ sở mã di sản, với ngân sách thời gian eo hẹp.
Kỹ sư

2

Trong cơ sở mã Java điển hình, tôi sẽ xem xét sử dụng các công cụ như PMD, FindBugs hoặc Sonar và sau đó tôi sẽ cố gắng hiểu các công cụ báo cáo (mã chết, mã không có giấy tờ, mã trùng lặp, v.v.)

Dựa trên các báo cáo tôi sẽ cố gắng tìm các lớp khác nhau của ứng dụng / trang web (lớp nghiệp vụ, DB, SQL, v.v.)

Nếu các lớp được ghép nối (html trong servlet, sql trong mã java) tôi sẽ bắt đầu trước bằng cách tách riêng từng bước này nên được coi là tách biệt và bạn có thể cam kết ở cuối mỗi bước (bằng cách bắt đầu một nhánh sau đó hợp nhất) .


1
Cảm ơn. Mặc dù câu trả lời của bạn có phần cụ thể về Java, nhưng thật thú vị khi thấy cách tiếp cận nhiều lớp của bạn ... bóc vỏ hành tây, có thể nói như vậy. Đôi điều suy nghĩ.
Kỹ sư

1

Từ mô tả của bạn, có vẻ như mã này đã đạt đến trạng thái không thể nhầm lẫn, điều đó có nghĩa là cách tiếp cận tốt nhất có khả năng là viết lại hoàn chỉnh. Các nhà phát triển sẽ có mức lương nhỏ hơn rất nhiều nếu có các công cụ chất lượng hoạt động để duy trì cơ sở mã lộn xộn. Có thể đi qua và dọn sạch mã không cần thiết cũ khỏi các thư mục, nhưng đó là một nhiệm vụ thủ công và bạn có thể sẽ không nhận được mọi thứ dù sao mà không có thời gian vô lý. Tôi chỉ đoán ở đây, nhưng tôi cá rằng chính mã làm việc cũng lộn xộn như cấu trúc tệp, điều đó có nghĩa là ngay cả khi bạn quản lý để lấy cơ sở mã được cắt theo mã hoạt động tích cực, nó vẫn sẽ là một cơn ác mộng để cập nhật hoặc sửa chữa bất cứ điều gì.

Tôi sẽ nhấn mạnh rằng nỗ lực cần thiết để có được mã hiện tại ở trạng thái có thể duy trì sẽ bằng hoặc lớn hơn nỗ lực để bắt đầu lại khi viết lại. một phần của việc duy trì bất cứ điều gì là biết khi nào nên "đưa nó ra sau nhà kho và bắn nó".


Thông thường tôi sẽ là 100% với bạn về phương pháp tung và viết lại. Nhưng trong trường hợp này (và ít nhất là bây giờ), tôi chỉ được trả tiền cho công việc để duy trì trang web, thay vì đại tu rộng rãi hơn sẽ mất vài tuần. Ngoài ra, ngay cả khi tôi muốn ngay bây giờ, tôi không thể tiếp tục thực hiện điều đó và giữ các hợp đồng khác mà tôi có khi đang di chuyển, vì tính sẵn sàng hàng tuần của tôi cho việc này bị hạn chế rõ ràng - hợp đồng chính của tôi phải được thực hiện theo Tối thiểu 40 giờ hàng tuần.
Kỹ sư

1
Không đồng ý với quăng và viết lại! Từ joelonsoftware.com/articles/fog0000000069.html ... "Có một lý do tinh tế mà các lập trình viên luôn muốn vứt bỏ mã và bắt đầu lại. Lý do là họ nghĩ rằng mã cũ là một mớ hỗn độn. Và đây là quan sát thú vị. : họ có thể sai. Lý do mà họ nghĩ rằng mã cũ là một mớ hỗn độn là vì một quy tắc cơ bản, cơ bản của lập trình: Đọc mã khó hơn viết mã. " Thay vào đó, tôi thực sự khuyên bạn nên tái cấu trúc: amazon.ca/Working-Effectively-Legacy-Michael-Feathers/dp/ trộm
Kyle Hodgson

1
@KyleHodgson đôi khi mã thực sự là một mớ hỗn độn và khi bạn đang ở thời điểm đó là một mớ hỗn độn để tìm mã trước khi đọc nó, đã đến lúc bắt đầu lại.
Ryathal

Vâng, tôi không nghĩ rằng nó rõ ràng như vậy, mặc dù cuốn sách đó có vẻ đáng đọc. Nó phụ thuộc rất nhiều vào kích thước / độ phức tạp của cơ sở mã và cơ thể ấm có sẵn để thực hiện công việc.
Kỹ sư

1

Trình thu thập dữ liệu web có thể giúp bạn xác định URL nào có thể truy cập được. Đặc biệt là nếu nó đủ thông minh để trích xuất các liên kết từ Flash hoặc JavaScript. Khi bạn có một danh sách các trang web, hãy xem qua chúng và liệt kê các tệp mà chúng đề cập đến. Bất cứ điều gì còn sót lại sau quá trình này nên được coi là mã chết.


1
Tôi hoàn toàn không đồng ý với câu cuối cùng của bạn. Trình thu thập thông tin chỉ có thể tìm ra các trang được liên kết với nhau dưới dạng biểu đồ có hướng với một hoặc nhiều điểm bắt đầu. Nhưng khi chúng ta nói về một trang web, cũng có cái gọi là "trang đích", liên kết đến các trang khác nhưng không có liên kết nào trỏ đến chúng. Ngoài ra, có thể có các phần cũ của giao diện quản trị cũng bị ngắt kết nối với các trang khác. Tôi hiện đang có một dự án loại này.
scriptin

0

Lưu ý: Tôi đặt dấu vào việc sử dụng cơ sở dữ liệu, trong khi bạn hỏi về việc sử dụng mã. Câu trả lời vẫn áp dụng cho cả hai trường hợp ở mọi điểm tôi đã đề cập.

Bạn đã trả lời một phần câu hỏi của riêng bạn trong đoạn cuối: xem những gì được truy cập trong khi ứng dụng đang chạy.

  1. Bạn có thể muốn lập hồ sơ cơ sở dữ liệu và yêu cầu trình hồ sơ ghi lại tất cả các truy vấn trong một ngày. Nó sẽ cung cấp cho bạn một cái nhìn tổng quan về các đối tượng cơ sở dữ liệu được sử dụng nhiều nhất, nhưng sẽ không cho biết những đối tượng nào không bao giờ được sử dụng. Ngoài ra, bạn vẫn phải cẩn thận với kết quả: ví dụ: một bảng có thể được sử dụng riêng thông qua các thủ tục được lưu trữ, nhưng khi bạn xem các truy vấn từ trình lược tả, nó sẽ xuất hiện như thể bảng không được sử dụng.

  2. Xem lại mã nguồn, tìm kiếm các truy vấn hữu ích hơn và sau khi thu thập tất cả các truy vấn, bạn có thể hiểu rõ về việc sử dụng cơ sở dữ liệu, không phải về tần suất (đây là nơi trình hồ sơ tiện dụng), nhưng về mặt sử dụng / không bảng đã sử dụng. Đáng buồn thay, đối với một codebase được viết kém / không được duy trì trong nhiều năm, nó có thể rất khó và dễ bị lỗi , đặc biệt là nếu các truy vấn được xây dựng linh hoạt (hãy tưởng tượng một phương thức, trong đó select, sử dụng một tham số làm tên của bảng; có thể biết các giá trị có thể có của tham số bằng cách chỉ nhìn vào mã nguồn là gì?).

  3. Phân tích tĩnh và một số trình biên dịch cũng có thể tiết lộ mã chết, nhưng vẫn không cung cấp cho bạn câu trả lời bạn muốn.

  4. Phân tích dữ liệu hoặc siêu dữ liệu cơ sở dữ liệu có thể tiết lộ một số thông tin thú vị. Ví dụ, nó có thể dễ dàng khẳng định rằng bảng LogonAudit(uniqueidentifier LogonAuditId, datetime LogonEvent, ...)không được sử dụng bất kỳ lâu hơn nếu nó có chứa 10 000 hồ sơ mỗi ngày cho những năm 2006-2009, và không có hồ sơ từ tháng Chín, 18 tháng năm 2009. Điều này cũng không đúng đối với một bảng chứa dữ liệu thụt vào hầu hết chỉ đọc.

Bốn điểm này với nhau sẽ cho bạn danh sách các bảng được sử dụng. Những cái còn lại được sử dụng hoặc không. Bạn có thể đưa ra các xác nhận và kiểm tra chúng, nhưng không có phạm vi kiểm tra đơn vị tốt, điều đó sẽ không dễ dàng. Bất kỳ cách "dễ dàng" cũng sẽ thất bại. Ví dụ: nếu bạn có một products_delme_not_usedbảng, bạn có thể khẳng định rằng bảng đó hoàn toàn không được sử dụng và kiểm tra "sản phẩm_delme_not_use" trong mã của bạn. Điều này rất lạc quan: không có gì lạ khi tìm thấy ứng cử viên DailyWTF như thế này trong một cơ sở mã cũ:

// Warning: WTF code below. Read with caution, never reuse it, and don't trust
// the comments.

private IEnumerable<Product> GetProducts()
{
    // Get all the products.
    return this.GetEntities<Product>("PRODUCT");
}

private IEnumerable<T> GetEntities<T>(string tableName)
{
    // Everyone knows that SQL is case sensitive.
    tableName = tableName.ToLower();

    if (tableName == "user" || tableName == "product")
    {
        // Those tables were renamed recently in the database. Don't have time
        // to refactor the code to change the names everywhere.
        // TODO: refactor the code and remove this `if` block.
        tableName += "s";
    }

    if (this.IsDelme(tableName))
    {
        // We have some tables which are marked for deletion but are still
        // used, so we adjust their name.
        tableName = this.Delme(tableName);
    }

    return this.DoSelectQuery<T>("select top 200 * from " + tableName);
}

private bool IsDelme(string name)
{
    // Find if the table is among candidates for removal.
    List<string> names = this.Query<string>("select Names from DelmeTables");
    return names.Contains(name);
}

private string Delme(string name)
{
    // Return the new name for a table renamed for deletion.
    return string.Join("_", new [] { name, "delme", "not", "used" });
}

Bạn có thể nhận ra rằng mã này thực sự sử dụng products_delme_not_usedbảng?

Nếu tôi là bạn tôi sẽ:

  1. Giữ tất cả các đối tượng cơ sở dữ liệu tại chỗ,
  2. Tái cấu trúc toàn bộ ứng dụng (nếu nó có giá trị),
  3. Tài liệu (trong khi tái cấu trúc) ứng dụng và cụ thể là sử dụng cơ sở dữ liệu.

Khi bạn hoàn thành hai bước cuối cùng, có lẽ bạn sẽ hiểu rõ hơn về việc sử dụng cơ sở dữ liệu, điều này sẽ giúp tìm ra tên của các bảng không được sử dụng nữa và có thể loại bỏ chúng một cách an toàn.


0

Với tôi, bạn cần có đủ thông tin để tạo ra một trích dẫn để tôi tập trung vào nỗ lực đó.

Tôi sẽ cố gắng xác định có bao nhiêu trường hợp sử dụng có liên quan đến trang web này. Điều này thường cung cấp cho bạn ý tưởng về mức độ lớn và phức tạp của trang web và mất bao nhiêu thời gian để tạo lại hoặc duy trì trang web / ứng dụng.

Vâng, đúng là đôi khi mã không được sử dụng nữa và nó sẽ khiến ứng dụng trông lớn hơn một chút so với thực tế, nhưng tôi không nghĩ rằng điều này sẽ ảnh hưởng đến con số nhiều nhất là hơn 20% , vì vậy tôi sẽ không lo lắng về phần đó.

Nhìn vào mã nguồn, các trang web và bảng cơ sở dữ liệu sẽ giúp bạn khám phá điều này.

Bạn cũng có thể muốn xem xét việc giới hạn số giờ mỗi tháng mà bạn sẽ dành cho dự án này với mức phí được xác định trước để bảo vệ chính mình.

Theo như khám phá những gì đang được sử dụng và không được sử dụng, thực sự không có cách nào dễ dàng. Các công cụ phân tích mã có thể giúp ích, nhưng vì bạn đang đối phó với một sự hỗn hợp tồi tệ như vậy, tôi không nghĩ rằng bất kỳ công cụ đơn lẻ nào tồn tại có thể giúp đỡ. Đối với từng khu vực cụ thể, bạn có thể tìm thấy một công cụ phân tích mã có thể giúp ích.

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.