it-swarm-vi.com

Khi nào thì viết lại LỚN câu trả lời?

Chỉ cần đọc câu hỏi về phần thưởng lớn và tôi nhớ một câu hỏi mà tôi muốn tự trả lời.

Tôi có một dự án khủng khiếp được truyền lại cho tôi, được viết bằng Java cũ, sử dụng Struts 1.0, các bảng có mối quan hệ không nhất quán hoặc không có mối quan hệ nào cả và thậm chí các bảng không có khóa chính hoặc trường có nghĩa là khóa chính nhưng hoàn toàn không phải là duy nhất. Bằng cách nào đó, hầu hết các ứng dụng "chỉ hoạt động". Hầu hết các trang được sử dụng lại (sao chép mã đã dán) và mã hóa cứng. Mọi người từng làm việc trong dự án đều nguyền rủa nó dưới hình thức này hay hình thức khác.

Bây giờ tôi đã cân nhắc từ lâu để đề xuất với quản lý cấp trên viết lại toàn bộ ứng dụng khủng khiếp này. Tôi đang dần cố gắng vào thời gian cá nhân nhưng tôi thực sự cảm thấy rằng điều này xứng đáng với một số tài nguyên chuyên dụng để thực hiện nó. Đọc các bài báo viết lại lớn, tôi có suy nghĩ thứ hai. Và điều đó không tốt khi tôi muốn thuyết phục cấp trên ủng hộ việc viết lại của mình. (Tôi làm việc trong một công ty khá nhỏ nên đề xuất có khả năng được chấp thuận)

TL; DR Khi nào thì viết lại câu trả lời lớn và bạn có thể sử dụng đối số nào để hỗ trợ nó?

288
Jonn

Xin lỗi, điều này sẽ còn dài, nhưng nó dựa trên kinh nghiệm cá nhân là cả kiến ​​trúc sư và nhà phát triển trên nhiều dự án viết lại.

Các điều kiện sau đây sẽ khiến bạn phải xem xét một số loại viết lại. Tôi sẽ nói về cách quyết định cái nào sẽ làm sau đó.

  • Thời gian tăng tốc của nhà phát triển là rất cao. Nếu phải mất nhiều thời gian hơn dưới đây (theo cấp độ kinh nghiệm) để tăng tốc cho một nhà phát triển mới, thì hệ thống cần phải được thiết kế lại. Theo thời gian tăng tốc, ý tôi là khoảng thời gian trước khi nhà phát triển mới sẵn sàng thực hiện cam kết đầu tiên của họ (trên một tính năng nhỏ) [.__.]
    • Mới ra trường - 1,5 tháng.
    • Vẫn xanh, nhưng đã làm việc trên các dự án khác trước đây - 1 tháng
    • Trung cấp - 2 tuần
    • Có kinh nghiệm - 1 tuần
    • Cấp cao - 1 ngày
  • Triển khai không thể được tự động, vì sự phức tạp của kiến ​​trúc hiện có
  • Ngay cả các sửa lỗi đơn giản cũng mất quá nhiều thời gian vì sự phức tạp của mã hiện có
  • Các tính năng mới mất quá nhiều thời gian và chi phí quá cao do sự phụ thuộc lẫn nhau của cơ sở mã (các tính năng mới không thể tách rời và do đó ảnh hưởng đến các tính năng hiện có)
  • Chu trình thử nghiệm chính thức mất quá nhiều thời gian vì sự phụ thuộc lẫn nhau của cơ sở mã hiện có.
  • Quá nhiều trường hợp sử dụng được thực thi trên quá ít màn hình. Điều này gây ra vấn đề đào tạo cho người dùng và nhà phát triển.
  • Công nghệ mà hệ thống hiện tại đang yêu cầu nó [.__.]
    • Các nhà phát triển chất lượng có kinh nghiệm trong công nghệ quá khó tìm
    • Nó không được dùng nữa (Không thể nâng cấp để hỗ trợ các nền tảng/tính năng mới hơn)
    • Đơn giản là có một công nghệ cấp cao biểu cảm hơn nhiều
    • Chi phí duy trì cơ sở hạ tầng của công nghệ cũ là quá cao

Những điều này là khá rõ ràng. Khi nào quyết định viết lại hoàn chỉnh so với xây dựng lại gia tăng thì chủ quan hơn, và do đó mang tính chính trị nhiều hơn. Điều tôi có thể nói với niềm tin là để nói rõ rằng đó là không bao giờ một ý tưởng tốt là sai.

Nếu một hệ thống có thể được thiết kế lại dần dần và bạn có sự hỗ trợ đầy đủ của tài trợ dự án cho việc đó, thì bạn nên làm điều đó. Đây là vấn đề, mặc dù. Nhiều hệ thống không thể được thiết kế lại tăng dần. Dưới đây là một số lý do tôi gặp phải để ngăn chặn điều này (cả về kỹ thuật và chính trị).

  • Kỹ thuật [.__.]
    • Sự kết hợp của các thành phần cao đến mức những thay đổi thành một thành phần không thể tách rời khỏi các thành phần khác. Việc thiết kế lại một thành phần duy nhất dẫn đến một loạt các thay đổi không chỉ cho các thành phần lân cận, mà còn gián tiếp đến tất cả các thành phần.
    • Ngăn xếp công nghệ phức tạp đến mức thiết kế nhà nước trong tương lai đòi hỏi nhiều thay đổi cơ sở hạ tầng. Điều này cũng cần thiết trong việc viết lại hoàn chỉnh, nhưng nếu nó được yêu cầu trong thiết kế lại gia tăng, thì bạn sẽ mất lợi thế đó.
    • Việc thiết kế lại một thành phần dẫn đến việc viết lại hoàn toàn thành phần đó dù thế nào đi nữa, bởi vì thiết kế hiện tại quá phổ biến đến nỗi không có gì đáng để tiết kiệm. Một lần nữa, bạn mất lợi thế nếu đây là trường hợp.
  • Chính trị
    • Các nhà tài trợ không thể được thực hiện để hiểu rằng thiết kế lại gia tăng đòi hỏi phải có cam kết lâu dài với dự án. Chắc chắn, hầu hết các tổ chức sẽ mất cảm giác ngon miệng cho việc rút ngân sách liên tục mà một thiết kế lại gia tăng tạo ra. Sự mất cảm giác này là không thể tránh khỏi khi viết lại, nhưng các nhà tài trợ sẽ có xu hướng tiếp tục hơn, vì họ không muốn bị tách ra giữa một hệ thống mới hoàn chỉnh một phần và hệ thống cũ lỗi thời một phần.
    • Người dùng của hệ thống quá gắn bó với "màn hình hiện tại" của họ. Nếu đây là trường hợp, bạn sẽ không có giấy phép để cải thiện một phần quan trọng của hệ thống (phần đầu). Thiết kế lại cho phép bạn khắc phục vấn đề này, vì chúng bắt đầu với một cái gì đó mới. Họ vẫn sẽ khăng khăng muốn có "cùng một màn hình", nhưng bạn có thêm một chút đạn để Đẩy lùi.

Hãy nhớ rằng tổng chi phí chuyển hướng tăng dần luôn luôn cao hơn so với việc viết lại hoàn chỉnh, nhưng tác động đến tổ chức thường nhỏ hơn. Theo tôi, nếu bạn có thể biện minh cho việc viết lại và bạn có các nhà phát triển siêu sao, thì hãy làm điều đó.

Chỉ làm điều đó nếu bạn có thể chắc chắn rằng có ý chí chính trị để xem nó hoàn thành. Điều này có nghĩa là cả người mua cuối cùng và người dùng cuối. Không có nó, bạn sẽ thất bại. Tôi cho rằng đây là lý do tại sao Joel nói rằng đó là một ý tưởng tồi. Điều hành người mua cuối cùng trông giống như một con Kỳ lân hai đầu đối với nhiều kiến ​​trúc sư. Bạn phải bán nó một cách mạnh mẽ và chiến dịch tiếp tục cho đến khi nó hoàn thành. Điều đó thật khó khăn và bạn đang nói về việc tôn vinh danh tiếng của mình trên một thứ mà một số người sẽ không muốn thấy thành công.

Một số chiến lược để thành công:

  • Tuy nhiên, nếu bạn làm, đừng cố chuyển đổi mã hiện có. Thiết kế hệ thống từ đầu. Nếu không, bạn đang lãng phí thời gian của bạn. Tôi chưa bao giờ thấy hoặc nghe nói về một dự án "chuyển đổi" mà không kết thúc một cách thảm hại.
  • Di chuyển người dùng đến một nhóm hệ thống mới tại một thời điểm. Xác định các đội có nỗi đau NHẤT với hệ thống hiện có và di chuyển chúng trước. Hãy để họ truyền bá tin tốt bằng lời nói. Bằng cách này, hệ thống mới của bạn sẽ được bán từ bên trong.
  • Thiết kế khung của bạn khi bạn cần nó. Đừng bắt đầu với một số tôi đã dành 6 tháng để xây dựng - khung này chưa bao giờ thấy mã thực.
  • Giữ ngăn xếp công nghệ của bạn càng nhỏ càng tốt. Đừng thiết kế quá mức. Bạn có thể thêm các công nghệ khi cần thiết, nhưng loại bỏ chúng là khó khăn. Ngoài ra, bạn càng có nhiều lớp, các nhà phát triển phải làm nhiều việc hơn. Đừng làm khó nó từ việc di chuyển.
  • Thu hút người dùng trực tiếp vào quá trình thiết kế, nhưng đừng để họ ra lệnh làm thế nào để làm điều đó. Kiếm niềm tin của họ bằng cách cho họ thấy rằng bạn có thể cung cấp cho họ những gì họ muốn tốt hơn nếu bạn tuân thủ các nguyên tắc thiết kế tốt.
328
Michael Meadows

Tôi đã tham gia hai bài viết lớn. Đầu tiên là một dự án nhỏ. Thứ hai là sản phẩm chính của một công ty phần mềm.

Có một số cạm bẫy:

  • viết lại luôn mất nhiều thời gian hơn dự kiến.
  • viết lại không có tác dụng/lợi ích trực tiếp cho khách hàng.
  • năng lực dành cho việc viết lại không được sử dụng để hỗ trợ khách hàng.
  • bạn sẽ mất chức năng viết lại trừ khi bạn có tài liệu 100%.

Viết lại hiếm khi là câu trả lời thực sự. Bạn có thể cấu trúc lại nhiều mã mà không mất bất cứ thứ gì và không có nhiều rủi ro.

Viết lại có thể là câu trả lời nếu:

  • bạn đang chuyển sang ngôn ngữ hoặc nền tảng khác.
  • bạn đang chuyển đổi khung/thành phần bên ngoài.
  • cơ sở mã hiện tại không thể duy trì được nữa.

Nhưng tôi thực sự khuyên bạn nên tiếp cận chậm bằng cách sử dụng tái cấu trúc. Nó ít rủi ro hơn và bạn giữ cho khách hàng của bạn hạnh phúc.

112
Toon Krijthe

Đã đến lúc viết lại khi:

Chi phí viết lại ứng dụng + duy trì ứng dụng viết lại ít hơn chi phí duy trì hệ thống hiện tại theo thời gian.

Một số yếu tố khiến việc duy trì giá hiện tại đắt hơn:

  • Ngôn ngữ này quá cũ đến nỗi bạn phải trả cho những người biết nó rất nhiều tiền để lập trình trong đó (COBOL).
  • . Điều này được gọi là "hỗ trợ cuộc sống phần cứng" và rất tốn kém vì khi các bộ phận trở nên khan hiếm hơn, chúng (có thể) sẽ tăng giá hoặc cuối cùng chúng sẽ hết.
  • Nó đã trở nên phức tạp đến mức //Here be dragons. bình luận là tất cả trên mã của bạn.
  • Bạn không thể viết bất kỳ dự án nào khác và thêm giá trị mới cho công ty vì bạn luôn vá con thú xấu xí này.
74
Ryan Hayes

Nếu bạn yêu cầu một sự thay đổi cơ bản trong kiến ​​trúc của dự án, thì đó là có thể thời gian để bắt đầu lại từ đầu.

Ngay cả với điều đó, có khả năng sẽ có một lượng lớn các mã vẫn đáng sử dụng lại trong dự án mới của bạn.

Cảnh báo công bằng mặc dù. Một dự án hiện tại sẽ được kiểm tra và cải tiến các quy tắc kinh doanh với vô số giờ sử dụng thực tế, điều không đúng với dự án bắt đầu từ đầu.

Tôi nghi ngờ một khung thời gian hoặc cảm giác ruột là một biện pháp thích hợp của một biện pháp quyết liệt như vậy. Bạn phải có rõ ràng, phòng thủhiểu rõ lý do để tham gia vào quá trình hành động này.

17
Dan McGrath

Mặc dù tôi đồng ý với câu trả lời của Kramii và ý kiến ​​của Joel, nhưng có những lúc thích hợp để viết lại. Trong các ứng dụng tồn tại lâu dài (tôi đang nói từ 10-20 năm trở lên), bảo trì sẽ ngày càng tốn kém hơn theo thời gian. Điều này là do mã ngày càng nhiều spaghetti-ish vì kiến ​​trúc ban đầu được hy sinh cho các bản vá bảo trì nhanh chóng. Ngoài ra, các nhà phát triển cho các công nghệ cũ trở nên hiếm hơn và đắt tiền hơn. Cuối cùng, phần cứng bắt đầu già đi và càng ngày càng khó tìm phần cứng mới, hệ điều hành, khung, v.v. để chạy ứng dụng cũ trên đầu trang. Ngoài ra, các doanh nghiệp phát triển và rất có thể một hệ thống cũ sẽ không đáp ứng được nhu cầu kinh doanh của tổ chức cũng như một hệ thống hoàn toàn mới có thể.

Vì vậy, bạn phải cân nhắc tất cả các chi phí bảo trì liên tục, cũng như các lợi ích tiềm năng của một hệ thống mới cho doanh nghiệp, chống lại chi phí viết lại từ đầu. Be rất bi quan trong ước tính của bạn về chi phí viết lại. Nó hầu như luôn luôn chi phí nhiều hơn và mất nhiều thời gian hơn bạn nghĩ.

12
RationalGeek

Dừng lại! Viết lại gần như không bao giờ câu trả lời. Thường xuyên hơn không, tái cấu trúc là một đặt cược tốt hơn.


Tất nhiên, có lần viết lại hợp lý:

  • Bạn đang chuyển sang một nền tảng mới, nơi các công cụ di chuyển không tồn tại (hoặc không thể được viết đủ rẻ).
  • Ứng dụng được viết lại là tầm thường.
  • Mã nguồn cho ứng dụng gốc bị mất và phục hồi tốn kém hơn so với viết lại.
  • Phần lớn các quy tắc kinh doanh được gói gọn trong ứng dụng hiện tại không còn được áp dụng.
  • Có ít người dùng tích cực của mã hiện có.
  • Bạn có tài nguyên (thời gian, tài năng và công cụ) để thực hiện viết lại.
  • Ứng dụng hiện tại không thể chạy trong môi trường sản xuất, vì lý do pháp lý hoặc thực tế.

Để hiểu lý do tại sao tôi khuyên bạn nên tái cấu trúc lại việc viết lại, hãy xem xét những gì liên quan đến việc viết lại. Bạn phải:

  1. Hiểu các sắc thái của những gì ứng dụng hiện có làm. Điều này thường không tầm thường khi bạn tính đến tất cả các quy tắc kinh doanh tinh tế mà nó gói gọn, môi trường (cả con người và kỹ thuật) mà nó vận hành và những ưu điểm và nhược điểm của giải pháp hiện tại. Thường xuyên hơn không, nơi duy nhất mà thông tin này tồn tại (nếu ở bất cứ đâu) là trong mã nguồn của ứng dụng hiện có. Thật không may là một trong những lý do chính để thực hiện viết lại là mã hiện tại rất khó hiểu và duy trì.

  2. Tái tạo chức năng này (hoặc phiên bản cập nhật của nó) trong một ứng dụng mới được thử nghiệm và đáng tin cậy. Mã hiện tại có thể không được hiểu bởi các nhà phát triển, nhưng thường được người dùng hiểu rõ. Nó có thể không đáp ứng nhu cầu kinh doanh hiện tại của họ, nhưng ít nhất họ có thể cho bạn biết ứng dụng làm gì trong những trường hợp khác nhau.

Ưu điểm lớn của tái cấu trúc là:

  • Bạn có thể lấy từng thứ một nhỏ.
  • Mọi thay đổi có thể được kiểm tra trong bối cảnh ứng dụng đang hoạt động.
  • Các giả thuyết về cách thức hoạt động của mã hiện tại có thể được kiểm tra bằng cách thực hiện các thay đổi nhỏ và quan sát những gì xảy ra.
  • Thay đổi thường có thể được gửi đến người dùng theo từng giai đoạn chứ không phải tất cả cùng một lúc.
  • Học hỏi từ giai đoạn đầu của tái cấu trúc có thể thông báo các giai đoạn sau của tái cấu trúc.
  • Nếu bạn từ bỏ quá trình một phần thông qua, vẫn sẽ có những lợi ích về cơ sở mã sạch hơn (trái ngược với việc viết lại mà phải được hoàn thành cung cấp bất kỳ lợi ích cho người dùng hoặc nhà phát triển).

Cũng cần nhớ rằng, nếu bạn viết lại, bạn được đảm bảo sẽ giới thiệu nhiều lỗi mới và gây rối cho cơ sở mã mới.

11
Kramii

Đồ họa này có thể giúp, đó là một chức năng của chất lượng cơ sở mã và giá trị kinh doanh của ứng dụng:

enter image description here

Biểu đồ giả vờ là một hướng dẫn về việc khi nào việc tái thiết kế phần mềm cũ là hợp lý và khi nào thì không. Ví dụ: nếu phần mềm có giá trị kinh doanh cao và chất lượng mã kém, thì việc tái thiết kế là hợp lý.

10
Tulains Córdova

Tôi nghĩ rằng tôi đang ở trong tình huống duy nhất trong sự nghiệp của mình, nơi viết lại lớn là câu trả lời:

Công ty sáp nhập, chồng chéo rất lớn trong chức năng hệ thống. Nhiều, nhiều hệ thống đã được hợp nhất và nghỉ hưu, và các hệ thống khác vẫn đang trong quá trình.

Tôi đã thừa hưởng một hệ thống từ công ty khác vẫn còn sống. Nó có một cơ sở mã khổng lồ, được sử dụng để hỗ trợ nhiều bộ phận rất giống với bộ phận của chúng tôi, nhưng với thiết kế và khung hoàn toàn khác. Chỉ có một lĩnh vực kinh doanh còn lại sử dụng nó, nó kiếm đủ tiền để giữ cho thứ này tồn tại trong trạng thái zombie. Tất cả các chuyên môn cũ đã biến mất, không có tài liệu. Gánh nặng hỗ trợ rất cao, với những thất bại mỗi tuần. Nó chưa được sáp nhập vào hệ thống công ty của chúng tôi, vì công ty chúng tôi chưa bao giờ hỗ trợ lĩnh vực kinh doanh đặc biệt này, vì vậy chúng tôi không có chức năng hoặc chuyên môn.

Có vẻ như đây là trường hợp cần viết lại. Có vẻ như tôi sẽ phải tìm ra người khổng lồ này, rút ​​ra các bit chức năng dành riêng cho doanh nghiệp này và viết lại các phần cần được thêm vào hệ thống hiện tại của chúng tôi. Khi đã xong, các hệ thống hiện tại của chúng tôi có thể hỗ trợ khu vực mới này và con thú này có thể thoát khỏi sự khốn khổ của nó. Nếu không tôi sẽ mất sự tỉnh táo của tôi.

8
Jay

Tôi đã làm việc cho một công ty phần mềm nhỏ có một vài ứng dụng DOS được nâng cấp để xử lý Y2K, viết lại dưới dạng ứng dụng Windows 16 bit và sau đó viết lại hoàn toàn dưới dạng một ứng dụng 32 bit với một tính năng 'nhỏ' bổ sung (cuối cùng chỉ được sử dụng bởi một khách hàng) đã tác động đến toàn bộ cấu trúc.

Việc chuyển mã 16 bit thành 32 có thể được thực hiện trong một tháng bởi một người, nhưng NOOOOOOOOO, chúng tôi đã phải viết lại mã để làm cho Soooooooooo tốt hơn nhiều. Điều này có thể được điều chỉnh cho các ngành công nghiệp khác, sẽ có đầy đủ thông số kỹ thuật và mã psuedo trước khi chúng bắt đầu. Thông số kỹ thuật đã được tạo, nhưng mất rất nhiều thời gian để viết mã thật. Nó được phát hành muộn, với nhiều lỗi hơn 16 bit 'bắt đầu' (đó là vào phiên bản v.3.0 và cuối cùng đến mức chúng tôi gần như thực hiện nó một tuần mà không có ai báo cáo lỗi mới).

Bạn nghĩ rằng viết lại cùng một ứng dụng 3-4 lần sẽ mang lại một số cải tiến, nhưng tôi không nghĩ rằng giao diện người dùng GUI có thể được chứng minh nhiều như vậy.

Đây là công việc CNTT đầu tiên của tôi với tư cách là người đứng đầu bộ phận hỗ trợ kỹ thuật. Tôi nên viết một cuốn sách về cách không phát triển phần mềm để phân phối. Rõ ràng là chúng tôi đã phạm nhiều sai lầm, nhưng thực tế là chúng tôi tiếp tục viết lại các ứng dụng cộng với sự bất tài.

7
JeffO

Tôi đã có một trường hợp rất giống với bạn, chỉ có mã không sử dụng Struts. Thay vào đó, những gì tôi đã làm là các khu vực đặc biệt nhảm nhí VÀ gây ra nhiều vấn đề. Cách tiếp cận mục tiêu này đã giúp chúng tôi tăng dần tốt hơn.

Trong khoảng thời gian 2 năm, chúng tôi đã nghiên cứu tái cấu trúc các bit và các mảnh cùng với công việc tăng cường. Chúng tôi luôn thực hiện một nhiệm vụ 'Làm cứng' trong kế hoạch dự án. Bằng cách tập trung vào các lĩnh vực cụ thể không hoạt động tốt, chúng tôi đã kiếm được nhiều tiền nhất. Những thứ làm việc chúng tôi để lại một mình. Điều quan trọng nữa là công việc này được thực hiện trong quá trình phát triển bình thường và được phát hành. Vấn đề với một bản viết lại lớn mà bạn gặp phải trong một năm hoặc hơn và sau đó khi bạn quay trở lại, mọi thứ đã thay đổi và một số lỗi khó chịu đã được xử lý và bạn mất ROI.

Chúng tôi không bao giờ viết lại toàn bộ. Chúng tôi đã ngừng sử dụng nền tảng đó cho công việc mới và đưa ra một nền tảng mới cho một dự án mới lớn. Điều đó đã được phê duyệt và chúng tôi đã cung cấp một sản phẩm tuyệt vời trong một khoảng thời gian hợp lý.

5
Bill Leeper

Vì vậy, ở đây tôi đang ngồi ở bàn làm việc, tôi bắt đầu viết lại mã cho mớ hỗn độn tuyệt đối này của một tệp aspx lớn, cơ sở dữ liệu đằng sau nó và thay thế giao diện MS Access thành MsQuery.

Chương trình asp này tràn ngập những thứ như

  • include(close.aspx) mà bên trong có một dòng mã đóng kết nối cơ sở dữ liệu mở cuối cùng.
  • Mã kế thừa chỉ nhận xét ngẫu nhiên
  • Không xem xét cho an ninh
  • Mã Spaghetti, hàng ngàn dòng của nó. Tất cả trong một tập tin.
  • Hàm và biến không có ý nghĩa rõ ràng đằng sau tên của chúng

Nếu chúng ta cần thay đổi một chút, thì giống như chơi năm trò chơi kal-toh đồng thời ở chế độ ác mộng.

Tôi được thuê để nhân rộng chức năng và tạo ra một sản phẩm có thể tùy chỉnh và bán được cho những người khác trong ngành. Vấn đề là điều này đã được viết trong hơn 10 năm qua để đáp ứng mọi nhu cầu kinh doanh đơn lẻ (vâng, tôi sẽ nói về năm hoặc sáu sigma của họ bằng mọi cách).

Nếu chúng tôi không muốn bán sản phẩm, có lẽ họ sẽ không cần viết lại vì đó là hầu hết những gì họ muốn - có lẽ không thanh lịch, nhưng không nên chi tiền về việc tạo mã Nice 'làm điều tương tự.'

5
Incognito

Giải pháp hiện tại không có quy mô.

Tôi đang nhìn bạn, MS Access.

4
user21007

Joel Spolsky có một bài viết tuyệt vời về điều này: Những điều bạn không bao giờ nên làm, Phần I

Từ tiêu đề bạn có thể nói, đó là một khía cạnh (anh ấy nói về lý do tại sao bạn không bao giờ nên ném mã) IMO, có rất nhiều sự thật với nó, gần đây tôi đã xem một video channel9 về Lễ kỷ niệm 25 năm của Excel, nơi một số nhà phát triển nói, làm thế nào ngay cả hôm nay nếu bạn nhìn vào nguồn, bạn sẽ kiểm tra sửa đổi và cuối cùng quay lại mã mà Excel đã sử dụng được viết cách đây 20 năm.

Bạn không thể chắc chắn 100% (ngay cả khi Netscape mắc lỗi (từ Bài viết của Joels)), [~ # ~] i [~ # ~] cảm thấy như bài báo của Joel là do Chúa gửi, bởi vì tôi có thể bi quan và thích vứt bỏ mã nghĩ rằng tôi luôn có thể viết nó tốt hơn lần thứ hai, nhưng giờ tôi mới nhận ra điều này chỉ rất nhiều .

Để đưa ra một câu trả lời cụ thể, tôi chỉ cần nói bạn cần thực hiện phân tích chi phí so với giá trị .

Thế giới thực của tôi: Một ứng dụng Silverlight Tôi đang phát triển v0.6 cho đến nay có một mớ hỗn độn các cuộc gọi không đồng bộ làm cho mã rất phức tạp. Kể từ khi tôi phát hiện ra Phần mở rộng phản ứng tuần này tôi thực sự muốn viết lại hầu hết mã, nhưng bây giờ tôi phải nói gì với khách hàng của mình? Chương trình hoạt động hoàn toàn tốt (với một số rò rỉ bộ nhớ tho) nhưng họ không quan tâm? Tôi không thể nói với họ Oh Tôi mất thêm 2-3 tuần nữa vì tôi muốn làm lại một cái gì đó. Tuy nhiên, tôi sẽ phân nhánh mã và viết lại /chơi với nó trong miễn phí thời gian.

Chỉ cần 2 xu của tôi ok!?

4
gideon

Có một trò đùa kinh điển về "nếu tôi sẽ đến X tôi sẽ không bắt đầu từ đây".

Tôi đã nhận một công việc một lần, trong đó động lực chính của nhà tuyển dụng là mang tài năng lên tàu để khởi động một bản viết lại quá hạn của một ứng dụng quan trọng trong kinh doanh. Câu hỏi tôi thất bại là, tại sao bạn lại kết thúc trong tình huống này ngay từ đầu? Đáng lẽ đó là một lá cờ đỏ, cho dù nguyên nhân là

  • quá nhiều áp lực để thêm chức năng để duy trì và tăng dần cấu trúc lại con thú,

  • quá ít khả năng trong bộ phận,

  • quá ít mua từ khách hàng hoặc quản lý cho công việc gia tăng,

hoặc bất cứ điều gì, và điều này gây ra lễ hội cho đến khi vấn đề đạt đến mức không thể chịu đựng được.

Vì vậy, tôi sẽ đồng ý với Joel rằng việc viết lại lớn có lẽ là một ý tưởng rất tồi - trừ khi bạn có bằng chứng chắc chắn rằng tất cả các lý do cơ bản đằng sau lý do tại sao một bản viết lại lớn dường như rất cần thiết đã được xử lý , bạn hoàn toàn có khả năng sẽ lặp lại vấn đề trong khóa học do.

2
Julia Hayward

Đó là câu trả lời khi viết lại cho phép tổ chức theo đuổi chiến lược gắn kết cạnh tranh hoặc cho phép nó phục vụ khách hàng tốt hơn theo cách mà kiến ​​trúc hiện tại không thể đáp ứng.

Thay vào đó, viết lại thường xảy ra để giảm bớt lo lắng quản lý:

  • mọi thứ nên ở trong .NET
  • nhà phát triển của chúng tôi nói rằng mã của chúng tôi hút,
  • chúng tôi đang tụt lại phía sau về mặt kỹ thuật
  • chúng tôi sẽ không thể tìm thấy các tài nguyên để hỗ trợ hệ thống của chúng tôi hoặc, rất thường xuyên,
  • đã mười năm rồi nên đã đến lúc.

Hầu hết những lo lắng này sẽ không thành hiện thực và nếu có, chúng có thể được xử lý. Điều cuối cùng, tuy nhiên, là tồi tệ nhất. Về cơ bản: chúng ta không có lý do.

Vâng, giống như xe hơi, một hệ thống sẽ bắt đầu có dấu hiệu hao mòn. Điều này có thể được giảm bớt bằng cách phục vụ thường xuyên. Bạn biết những gì họ nói về cách bảo trì phòng ngừa một chút đi một chặng đường dài. Là một khoản đầu tư, dịch vụ thường xuyên (nghĩa là tái cấu trúc và tiêu chuẩn hóa) hầu như sẽ luôn mang ít chi phí hơn so với viết lại.

Tuy nhiên, chúng tôi phải dự đoán rằng việc viết lại cuối cùng sẽ là cần thiết. Đặt ngày và lên kế hoạch dự kiến ​​cho nó, nhưng vì ngày càng đến gần sự chậm trễ có lợi cho việc thực hiện các mục tiêu chiến lược khác cho đến khi bạn có một lý do thuyết phục như ...

Trong những năm gần đây, chúng tôi đã mất cơ hội giành được các tài khoản lớn vì chúng tôi không thể đáp ứng nhu cầu của họ một cách kịp thời hoặc tốn kém. Hệ thống của chúng tôi sẽ được viết lại bằng kiến ​​trúc mở rộng cho phép cắm các tùy chỉnh (và không được mã hóa cứng như chúng tôi hiện đang làm). Điều này sẽ giảm đáng kể thời gian và chi phí cho việc phục vụ khách hàng có nhu cầu đặc biệt. Chúng tôi sẽ giành được nhiều tài khoản hơn và đáp ứng tốt hơn nhu cầu của khách hàng hiện tại của chúng tôi.

2
Mario T. Lanza

Tôi nghĩ rằng lý do chính mà biện minh cho việc viết lại là để thay đổi nền tảng. Ví dụ: nếu bạn có ứng dụng GUI trên máy tính để bàn Windows và chủ sở hữu công ty quyết định họ muốn phiên bản tiếp theo là ứng dụng dựa trên web. Mặc dù không phải lúc nào cũng vậy, theo kinh nghiệm của tôi, phần lớn thời gian này sẽ yêu cầu viết lại, trừ khi các nhà phát triển ban đầu viết mã rất mô-đun và có thể tái sử dụng (hầu như không xảy ra).

2
Craig

Theo Joel, các bản viết lại lớn là lỗi chiến lược tồi tệ nhất mà một công ty có thể mắc phải:

Những điều bạn không bao giờ nên làm, Phần I

... Điều quan trọng cần nhớ là khi bạn bắt đầu từ đầu, hoàn toàn không có lý do để tin rằng bạn sẽ làm một công việc tốt hơn bạn đã làm lần đầu tiên. Trước hết, có lẽ bạn thậm chí không có cùng một nhóm lập trình làm việc trên phiên bản một, vì vậy bạn thực sự không có "nhiều kinh nghiệm". Bạn sẽ lại mắc phải hầu hết các lỗi cũ và giới thiệu một số vấn đề mới không có trong phiên bản gốc.

Câu thần chú cũ xây dựng một thứ để vứt đi là nguy hiểm khi áp dụng cho các ứng dụng thương mại quy mô lớn. Nếu bạn đang viết mã bằng thực nghiệm, bạn có thể muốn trích xuất hàm bạn đã viết tuần trước khi bạn nghĩ về một thuật toán tốt hơn. Tốt rồi. Bạn có thể muốn cấu trúc lại một lớp để dễ sử dụng hơn. Điều đó cũng tốt Nhưng vứt bỏ toàn bộ chương trình là một sự điên rồ nguy hiểm và nếu Netscape thực sự có sự giám sát của người lớn với kinh nghiệm trong ngành phần mềm, họ có thể đã không tự bắn vào chân mình quá tệ.

2
user3287

Khi chuyển sang một công nghệ hoàn toàn mới là cần thiết để cung cấp chức năng mong muốn.

"Hoàn toàn mới": nếu bạn dự định viết lại nhưng sử dụng cùng một nền tảng, thì tái cấu trúc và tái cấu trúc hợp lý gần như chắc chắn là giải pháp tốt hơn. "Nền tảng", như được sử dụng ở đây, hơi mơ hồ - xem xét nó bao gồm ngôn ngữ và có lẽ là HĐH (mở rộng từ Linux sang Windows hoặc ngược lại), nhưng có lẽ không phải là khung (ví dụ, thay thế Struts bằng Spring).

"Cần cung cấp chức năng mong muốn": ngay khoảng năm 2000, tôi đã khởi xướng một dự án để viết lại một thành phần máy chủ chính trong Java từ C++ để cho phép phân luồng ngoài luồng, bộ đệm đối tượng, và tại thời điểm đó, có nhiều thư viện phân luồng cho C++ mà chúng tôi sẽ phải hỗ trợ và việc kích hoạt luồng nhiều mã cơ sở dữ liệu của chúng tôi sẽ cần phải viết lại gần như toàn bộ. Đối với các giao dịch do khách hàng kiểm soát. .. sẽ không xảy ra với kiến ​​trúc cũ.

Ngay cả khi đó, tôi không chắc chắn rằng mình đã viết lại, ngoại trừ việc tôi có kiến ​​thức chi tiết về hành vi của hệ thống hiện tại và đó là mã tương đối sạch sẽ đã phát triển rất nhiều mụn cóc trong 11 năm của cuộc đời.

1
Anon

Tôi có thể tưởng tượng các tình huống giả định trong đó tôi có thể loại bỏ cơ sở mã hiện có (các tình huống giả định trong đó các quả bóng bucky có trọng lượng và khối lượng bằng không, trong đó không ai quan tâm nếu chúng ta mất hàng tuần hoặc hàng tháng năng suất khi chúng ta tranh giành để thêm các tính năng và lỗi bị bỏ qua sửa lỗi vào hệ thống và trong đó hệ thống rất tầm thường và bị ghét bởi một tổ chức mà tôi có thể thay thế toàn bộ mọi thứ và đội quân máy chủ bằng notepad ++ và netbook trong mười phút và tăng năng suất và đạo đức của mọi người trên bảng.)

Đối với hầu hết mọi kịch bản trong thế giới thực, tôi chỉ khuyên bạn nên tái cấu trúc tại chỗ. ^ _ ^. Có quá nhiều chi phí ẩn, không lường trước được để viết lại khi các yêu cầu kinh doanh và pháp lý không có giấy tờ bắt đầu xuất hiện và những phút cuối cùng hack mọi thứ vào phút cuối bắt đầu xảy ra.

== Tái cấu trúc tại chỗ cho mục đích tốt hơn và công cụ ==

Tái cấu trúc mã kế thừa theo cách tiếp cận gia tăng cũ thông thường,

  1. Nếu bạn có cơ hội chuyển đổi sang UML và ghi lại kiến ​​trúc nhỏ bé đó là gì.
  2. Nếu bạn đang kiểm soát phiên bản, hãy xem xét việc tạo một số báo cáo khuấy mã và tìm ra các tệp và phần tệp đã được thay đổi thường xuyên nhất. Hãy ghi lại những điều này vì chúng có thể sẽ là lĩnh vực bạn muốn giải quyết trước tiên.
  3. Trước khi bạn thay đổi bất kỳ mã nào, hãy luôn cố gắng thêm một số phạm vi kiểm tra (ngay cả các kiểm tra chức năng ngăn xếp đầy đủ xấu xí cũng sẽ làm được). Nếu xử lý logic trích xuất mã thủ tục lộn xộn lớn, bạn dự định thay đổi thành một số phương thức hoặc hàm được đặt tên hợp lý và nếu có thể, hãy thêm một số trường hợp kiểm tra xác minh phương thức mới của bạn. làm cho bất cứ điều gì thần thánh khủng khiếp bạn phải làm và nếu có thể tối ưu hóa sự thay đổi nếu đó là một cái gì đó thường được điều chỉnh như độ rộng lề hoặc tiêu đề để nó sẽ được cập nhật thêm một chút để cập nhật vào lần tiếp theo.
  4. Sử dụng mẫu bộ điều hợp và tìm cách ẩn các bit kế thừa của mã kế thừa dưới một lớp các lớp và phương thức được đặt tên logic để cho hầu hết các tác vụ phổ biến mà bạn và các nhà phát triển khác thực hiện, bạn không cần phải lo lắng về các bit đáng sợ đang diễn ra phía sau lưng của bạn đằng sau những phương pháp và lớp học sạch đẹp nhỏ bé mà bạn đã giấu mã di sản đó phía sau - giống như những gia đình Nice giữ những thành viên gia đình zombie giết người bị biến dạng trong chuồng trại để họ không làm hỏng ngày này qua ngày khác nông trại . . . bình thường.
  5. Khi bạn tiếp tục thu nhỏ và dọn sạch các phần của mã tiếp tục tăng phạm vi kiểm tra của bạn. Bây giờ bạn có thể đào sâu hơn nữa và "viết lại" nhiều mã hơn nữa khi cần/mong muốn với độ tin cậy ngày càng tăng.
  6. Lặp lại hoặc áp dụng các phương pháp tái cấu trúc bổ sung để tiếp tục cải thiện cơ sở mã của bạn.

Phân nhánh theo trừu tượng

  1. Xác định điểm gặp sự cố trong mã bạn muốn xóa (lớp lưu giữ, trình tạo pdf, cơ chế kiểm đếm hóa đơn, trình tạo widget, v.v.).
  2. chạy (viết nếu cần thiết) một số trường hợp kiểm tra chức năng (tự động hoặc thủ công nhưng bạn biết tự động) đối với cơ sở mã nhắm vào chức năng này cùng với hành vi chung.
  3. Trích xuất logic liên quan đến thành phần đó từ cơ sở nguồn hiện có vào một lớp với một số giao diện hợp lý.
  4. Xác minh tất cả mã hiện đang sử dụng giao diện mới để thực hiện hoạt động X được phân tán ngẫu nhiên trước đó trong toàn bộ mã (Grep cơ sở mã, thêm dấu vết vào lớp mới và xác minh các trang sẽ gọi nó, v.v.), và đó bạn có thể kiểm soát việc triển khai nào sẽ được sử dụng bằng cách sửa đổi một tệp duy nhất. (sổ đăng ký đối tượng, lớp nhà máy, bất cứ thứ gì IActivityXClass = Settings.AcitivtyXImcellerer ();)
  5. chạy lại các trường hợp kiểm tra chức năng xác minh mọi thứ vẫn hoạt động với tất cả Hoạt động X ném vào lớp mới của bạn.
  6. Viết các bài kiểm tra đơn vị nếu có thể xung quanh lớp trình bao X hoạt động mới.
  7. triển khai một lớp mới với logic spaghetti ít điên rồ hơn so với triển khai kế thừa tuân thủ cùng giao diện với lớp kế thừa.
  8. xác minh rằng lớp mới vượt qua các bài kiểm tra đơn vị bạn đã viết cho lớp kế thừa.
  9. cập nhật mã của bạn bằng cách thay đổi sổ đăng ký/nhà máy/bất cứ điều gì để sử dụng lớp mới thay vì lớp cũ.
  10. xác minh rằng các bài kiểm tra chức năng của bạn vẫn vượt qua.

Nguyên tắc đóng mở và lớp logic/lớp kiên trì kinh doanh chung

Ở một mức độ nào đó, bạn có thể thoát khỏi việc tách lớp trình bày, kinh doanh và kiên trì của mình và viết một ứng dụng mới hoàn toàn tương thích ngược với giải pháp cũ hoặc tối thiểu vẫn có thể xử lý dữ liệu được nhập bằng giải pháp cũ. Tôi có thể sẽ không đề xuất phương pháp này nhưng đôi khi nó là một sự thỏa hiệp hợp lý về thời gian/lịch trình/tài nguyên/chức năng mới cần thiết.

  • Tối thiểu tách lớp trình bày ra khỏi lớp kinh doanh và kiên trì.
  • thực hiện một lớp trình bày mới và tốt hơn sử dụng cùng một lớp kinh doanh và kiên trì chung.
  • Xác minh rằng dữ liệu được tạo bằng ui mới không phá vỡ ui cũ. (bạn sẽ ở trong nước nóng nếu người dùng công cụ mới làm gián đoạn người dùng công cụ cũ). Nếu bạn đang cố gắng để tương thích ngược hoàn toàn, bạn nên lưu tất cả mọi thứ vào cùng một lớp. Nếu bạn chỉ muốn tương thích về phía trước với công cụ mới thì hãy sử dụng cơ sở dữ liệu mới và các bảng mới hoặc bảng mở rộng để theo dõi dữ liệu không có trong hệ thống cũ.
  • Đối với chức năng mới và lớp kiên trì cần thêm các bảng và phương thức mới không thay đổi logic kế thừa hiện có hoặc thêm các cột, các ràng buộc cho các bảng hiện có. ví dụ. nếu bạn cần bắt đầu theo dõi liên hệ khẩn cấp của nhà tuyển dụng và một số trường khác không sửa đổi bảng nhân viên hiện tại (chúng tôi không biết giả định nào về dữ liệu kế thừa về bảng đó), hãy thêm bảng mở rộng worker_ext id, worker_id, khẩn_contact_id, etc_id.
  • Từ từ di chuyển người dùng vào hệ thống mới. nếu có thể, hãy đặt hệ thống cũ vào chế độ chỉ đọc hoặc chỉ cần thêm một số cảnh báo cho người dùng biết nó sẽ không còn khả dụng sau ngày X.
  • thực hiện bất kỳ ưu tiên hi bỏ lỡ chức năng hoặc yêu cầu kinh doanh trong ui mới
  • cuộn qua cơ sở người dùng.
  • tiếp tục làm sạch logic nghiệp vụ và lớp người dùng kiên trì các phương pháp tái cấu trúc khác.
0
Keith Brings

Tôi muốn nói rằng có một thể loại thứ ba trong không gian Refactor vs Rewrite ... Và việc cập nhật các phiên bản ngôn ngữ, trình biên dịch và thư viện của bạn ... Đôi khi chỉ cần áp dụng các kỹ thuật mã hóa hiện đại có lợi ích rất lớn.

Lấy C # làm ví dụ, mã v7 viết sạch hơn, an toàn hơn và súc tích hơn v2 .. Những thứ như toán tử kết hợp Elvis và null giúp đỡ rất nhiều.

Chuyển đổi trình biên dịch cũng có thể thổi sức sống mới vào mã cũ. Vì vậy, các thư viện mới có thể giúp mọi thứ dễ dàng hơn để làm việc và triển khai ... Mạng là một ví dụ tuyệt vời về phổ độ khó thực hiện.

Ngoài ra- các hệ thống linux được nhúng ... Hãy suy nghĩ về việc cài đặt các công cụ mới - chuyển sang git từ svn. hoặc thêm Vi vào hệ thống của bạn, v.v.

Nó không phải luôn luôn là một bộ tái cấu trúc so với viết lại .. Kiến trúc của bạn có thể cần được cải thiện, nhưng nó hoạt động ... có lẽ bạn chỉ cần nghĩ về cách viết mã của mình, v.v.

0
visc

Để quyết định thời điểm mà bạn nên bắt đầu lại, bạn cần tìm ra giá trị tiếp tục cho dự án hiện tại của bạn không bằng giá trị khi bắt đầu lại.

Lý do điều này rất khó là vì bạn ước tính chính xác tốc độ phát triển của nhóm trong dự án mới cho đến khi bạn thực sự bắt đầu nó. Điều đó nói rằng, nếu sử dụng ước tính RẤT bảo thủ về tốc độ phát triển của bạn cho dự án mới, dự án được ước tính mang lại lợi tức đầu tư đáng giá, thì bạn có một trường hợp kinh doanh để bắt đầu từ đầu.

0
Nobody

Với số liệu của tôi, bạn phải đáp ứng hai điều kiện để chứng minh việc viết lại:

  1. Sau khi viết lại, các tính năng mới sẽ dễ dàng hơn/nhanh hơn/ít lỗi hơn để viết
  2. Việc viết lại sẽ mất ít hoặc bằng thời gian hơn so với việc thêm tính năng mới hiện tại.

Thậm chí sau đó bạn muốn giới hạn phạm vi viết lại của bạn. Ví dụ, chúng tôi đã có một số phần mềm kế thừa tại một công ty được viết bằng C++ với suy nghĩ của một lập trình viên C không biết về mô đun hóa. Kết quả cuối cùng là mã speghetti dưới dạng một máy trạng thái hữu hạn kéo dài nhiều lớp và DLL. Chúng tôi có một yêu cầu mới rất khác so với các giả định được xây dựng trong mã và sẽ trở thành một phần của giá trị gia tăng được cấp bằng sáng chế của công ty cho khách hàng của mình.

Sau khi dành thời gian với mã triển khai các tính năng khác, tôi đã có ý tưởng thực sự tốt về việc mất bao lâu để tìm ra câu lệnh chuyển đổi nào tôi cần thay đổi, v.v. Đề xuất của tôi là viết lại phần mã đó cỗ máy trạng thái hữu hạn khổng lồ - nó sẽ khiến tôi mất ít thời gian hơn so với việc mở rộng mã hiện có. Tôi đã có thể hợp nhất thành một DLL, trước đây là ba và cung cấp một cấu trúc hướng đối tượng nhiều hơn, giúp thực hiện chức năng mới quan trọng dễ dàng hơn cùng với việc làm cho nó dễ dàng hơn thêm chức năng mới.

Có ba ứng dụng khác sử dụng các thư viện cần viết lại, vì vậy tôi không muốn phải viết lại hoàn toàn các chương trình đó. Phạm vi được giới hạn trong thư viện và những gì cần thiết để liên kết thư viện với phần mềm hiện có. Ước tính của tôi không được xa, và công việc tự trả tiền. Ngay sau khi thiết kế lại, tôi được giao nhiệm vụ thêm một tính năng mới. Điều gì sẽ đưa tôi một tuần với cấu trúc cũ chỉ đưa tôi một ngày với cấu trúc mới.

0
Berin Loritsch

OP không chỉ ra phạm vi của dự án, nhưng manh mối chính tôi đã lấy là "được viết bằng [ngôn ngữ/phương ngữ] cũ bằng cách sử dụng [libs] cũ" mà theo tôi là các trình điều khiển chính của việc viết lại. Trên thực tế, hầu hết các dự án tôi đã tham gia vào bất kỳ tuổi thọ thị trường quan trọng nào cuối cùng cũng nhận ra rằng việc cập nhật chỗ ở cho trình biên dịch/trình thông dịch/hệ điều hành là một nhiệm vụ quan trọng trong việc duy trì cơ sở mã.

Nói tóm lại, tôi sẽ lên kế hoạch viết lại theo từng giai đoạn, ưu tiên cập nhật trước trong libs. Có thể là trên đường đi, bạn có thể lén theo dõi các tối ưu hóa khác, nhưng thực tế là bạn dự định trì hoãn một số thay đổi cho giai đoạn sau có thể là một cách tuyệt vời để giữ đúng tiến độ và tránh bị "mắc kẹt".

0
MarkHu