Tôi đã thay đổi một chữ ký phương thức và hiện có hơn 25.000 lỗi. Gì bây giờ?


166

Gần đây tôi đã bắt đầu một công việc mới, nơi tôi đang làm việc trên một ứng dụng rất lớn (15M loc). Trong công việc trước đây của chúng tôi, chúng tôi có một ứng dụng lớn tương tự nhưng (tốt hơn hay tồi tệ hơn), chúng tôi đã sử dụng OSGi, điều đó có nghĩa là ứng dụng được chia thành nhiều dịch vụ siêu nhỏ có thể thay đổi, biên dịch và triển khai độc lập. Ứng dụng mới này chỉ là một cơ sở mã lớn, có thể có một vài dll.

Vì vậy, tôi cần thay đổi giao diện của lớp này, vì đó là những gì ông chủ của tôi yêu cầu tôi làm. Ban đầu, họ đã viết nó với một số giả định không khái quát quá tốt, và trong một thời gian họ đã tránh được vấn đề tái cấu trúc vì nó quá chặt chẽ. Tôi đã thay đổi giao diện và hiện có hơn 25000 lỗi. Một số lỗi trong các lớp học với những cái tên nghe có vẻ quan trọng như "XYZPriceCalculator" mà reaaallykhông nên phá vỡ. Nhưng tôi không thể khởi động ứng dụng để kiểm tra xem nó có hoạt động không cho đến khi tất cả các lỗi được giải quyết. Và nhiều bài kiểm tra đơn vị tham chiếu trực tiếp giao diện đó hoặc được ghép nối với các lớp cơ sở tham chiếu giao diện đó, vì vậy chỉ cần sửa chúng là một nhiệm vụ khá lớn. Thêm vào đó, tôi thực sự không biết làm thế nào tất cả các mảnh này khớp với nhau, vì vậy ngay cả khi tôi có thể bắt đầu, tôi thực sự không biết nó sẽ trông như thế nào nếu mọi thứ bị hỏng.

Tôi chưa bao giờ thực sự phải đối mặt với một vấn đề như thế này trong công việc cuối cùng của tôi. Tôi làm gì?


7
Bạn sẽ cần cung cấp cho chúng tôi thêm thông tin về các loại lỗi và "lớp này" là gì, chúng tôi không bận tâm đến độc giả.
tên gì là

137
"hơn 25000 lỗi" những con số như vậy hiển thị trong VS thường sai. Có một vài lỗi, nhưng với việc xây dựng một dll thường được sử dụng bị hỏng, các bản dựng khác cũng thất bại, làm tăng số lỗi thiên văn. Tôi luôn bắt đầu sửa với thông báo lỗi đầu tiên được tìm thấy trong đầu ra bản dựng, không phải trong danh sách lỗi.
Bernhard Hiller

13
Tôi muốn xem chữ ký trước và sau trên phương thức bạn đã thay đổi. BTW - Lỗi 25k không thực sự nghe có vẻ quá nhiều để xử lý. Tàn nhẫn có, nản chí, có, không thể quản lý, không.
jmoreno

46
Một giao diện công cộng là một hợp đồng. Đừng phá vỡ các hợp đồng như vậy - tạo ra những hợp đồng mới.
Matthew đọc

6
25000 lỗi!? Houston, chúng tôi có một vấn đề. Chắc chắn hoàn nguyên thay đổi và nói chuyện với người quản lý của bạn, giải thích cho anh ta rằng bạn có thể phải tạo một giao diện mới hoàn toàn.
Code Whisperer

Câu trả lời:


349

25000 lỗi về cơ bản có nghĩa là "không chạm vào đó". Thay đổi nó trở lại. Tạo một lớp mới có giao diện mong muốn và từ từ chuyển người tiêu dùng của lớp sang lớp mới. Tùy thuộc vào ngôn ngữ, bạn có thể đánh dấu lớp cũ là không dùng nữa, điều này có thể gây ra tất cả các loại cảnh báo trình biên dịch, nhưng thực tế sẽ không phá vỡ bản dựng của bạn.

Thật không may những điều này xảy ra trong các cơ sở mã cũ. Bạn không thể làm được gì nhiều ngoài việc từ từ làm mọi thứ tốt hơn. Khi bạn tạo các lớp mới, hãy đảm bảo rằng bạn đã kiểm tra chúng đúng cách và tạo chúng bằng các nguyên tắc RẮN để chúng sẽ dễ dàng thay đổi hơn trong tương lai.


79
Nó không nhất thiết phải là một lớp mới . Tùy thuộc vào ngôn ngữ và hoàn cảnh, nó có thể là một chức năng, giao diện, đặc điểm, v.v.
Jan Hudec

33
Nó cũng giúp nếu giao diện cũ có thể được thay thế bằng trình bao bọc tương thích xung quanh giao diện mới.
Jan Hudec

79
Đôi khi, 25000 lỗi thực sự có nghĩa là Chúng tôi chưa bao giờ dám chạm vào điều đó, nhưng bây giờ khi có người mới đến, hãy giao cho anh ta nhiệm vụ dọn dẹp sạch sẽ của Augean.
mouviciel

13
@theDmi: Tôi đồng ý, 1 thay đổi và 25k lỗi rất có thể có nghĩa là tối đa 2,5k thay đổi và tôi sẽ không ngạc nhiên khi thấy rằng đó là khoảng 250. Dù sao thì cũng có thể làm được.
jmoreno

33
25000 lỗi đó có thể được sửa chữa bằng một thay đổi duy nhất. Nếu tôi phá vỡ lớp cơ sở của một người thừa kế khổng lồ, mỗi một trong các lớp dẫn xuất sẽ phát sinh lỗi về cơ sở không hợp lệ, mỗi lần sử dụng các lớp đó sẽ phát sinh lỗi về lớp không tồn tại, v.v. Hãy tưởng tượng đó là "getName" và tôi đã thêm một cuộc tranh cãi. Việc ghi đè trong lớp triển khai "HasAName" hiện không hoạt động (lỗi) và mọi thứ kế thừa từ bây giờ đều phát sinh lỗi (tất cả 1000 lớp), cũng như mỗi khi tôi tạo một phiên bản của bất kỳ trong số chúng (24x mỗi lớp trên Trung bình cộng). Cách khắc phục là ... một dòng.
Yakk

80

Chia và chinh phục với tái cấu trúc

Thông thường, chia nhỏ thay đổi mà bạn cần thực hiện thành các bước nhỏ hơn có thể giúp ích vì sau đó bạn có thể thực hiện hầu hết các bước nhỏ hơn theo cách hoàn toàn không phá vỡ phần mềm. Công cụ tái cấu trúc giúp rất nhiều với các nhiệm vụ như vậy.

Phân phát

Đầu tiên, xác định những thay đổi nhỏ nhất có thể (về mặt thay đổi logic, không phải về mặt LoC đã thay đổi) tổng hợp với thay đổi bạn muốn đạt được. Đặc biệt là cố gắng cô lập các bước là tái cấu trúc thuần túy và có thể được thực hiện bằng các công cụ.

Chinh phục

Đối với các trường hợp phức tạp như của bạn, có thể thực hiện một lần tái cấu trúc nhỏ tại một thời điểm và sau đó để vấn đề được giải quyết, để tất cả các hệ thống tích hợp liên tục có thể xác minh thay đổi và có thể nhóm thử nghiệm cũng đã xem xét. Điều này xác nhận các bước bạn thực hiện.

Để thực hiện tái cấu trúc cụ thể, bạn hoàn toàn cần hỗ trợ công cụ cho trường hợp bạn có 25.000 trang web gọi phương thức bạn muốn thay đổi. Có thể các tác phẩm tìm kiếm và thay thế cũng vậy, nhưng đối với trường hợp quan trọng như vậy, tôi sẽ sợ điều đó.

Thí dụ

Ví dụ, trong C #, có thể sử dụng Resharper để thay đổi chữ ký của phương thức. Nếu thay đổi đủ đơn giản, ví dụ: thêm một tham số mới, thì bạn có thể chỉ định giá trị nào sẽ được sử dụng tại các trang web cuộc gọi có lỗi biên dịch.

Sau đó, bạn đang ở một cơ sở mã miễn phí lỗi ngay lập tức và có thể chạy tất cả các bài kiểm tra đơn vị, sẽ vượt qua, bởi vì đó chỉ là một cấu trúc lại.

Khi chữ ký của phương thức có vẻ tốt, bạn có thể đi và thay thế các giá trị mà Resharper đã thêm làm đối số cho tham số vừa được giới thiệu. Đây không phải là tái cấu trúc nữa, nhưng bạn có cơ sở mã không có lỗi và có thể chạy thử nghiệm sau mỗi dòng bạn thay đổi.

Đôi khi điều đó không làm việc

Đây là một cách tiếp cận rất hữu ích cho các trường hợp như của bạn, nơi bạn có rất nhiều trang web cuộc gọi. Và hiện tại bạn đã có phần mềm hoạt động, vì vậy có thể thực hiện các bước tái cấu trúc nhỏ để thay đổi chữ ký chỉ một chút, sau đó thực hiện một bước khác.

Thật không may, nó sẽ không hoạt động nếu thay đổi chữ ký quá phức tạp và không thể chia thành các thay đổi nhỏ hơn. Nhưng điều này là hiếm; chia vấn đề thành các vấn đề nhỏ hơn thường cho thấy điều đó có thể.


12
Điều này. Tái cấu trúc nếu bạn có thể (một cách an toàn), nếu không bạn cần một sự di chuyển thích hợp.
sleske

3
Và vì yêu thích bất cứ điều gì, vui lòng sử dụng các công cụ tái cấu trúc tích hợp trong IDE của bạn, thay vì chỉ thay đổi chữ ký phương thức (ví dụ) cục bộ và sau đó sẽ sửa chữa các lỗi do đó.
KlaymenDK

36

Làm rõ nhiệm vụ của bạn với sếp để giúp anh ta hiểu vấn đề và nhu cầu của bạn như một nhà phát triển phần mềm chuyên nghiệp.

Nếu bạn là thành viên của một nhóm, hãy tìm nhà phát triển chính và nhờ anh ấy tư vấn.

Chúc may mắn.


15
Đây là bước đầu tiên tôi thực hiện - "Tôi là một thiếu niên và ông chủ của tôi đã bảo tôi làm một việc và bây giờ tôi nhận được một thông báo lỗi rất lớn, nhưng ông chủ của tôi đã không nói với tôi về điều đó." Bước 1: "Này ông chủ, tôi đã làm điều đó, nhưng bây giờ tôi đã nhận được 25 nghìn lỗi. Điều đó đáng lẽ phải xảy ra, hoặc ..."
Pimgd

28

Đừng chạm vào nó. Đừng cam kết bất cứ điều gì.

Thay vào đó, ngồi xuống ghế của bạn và hét lên "Heeeeelp !!!!!" càng to càng tốt.

Chà, không chính xác như thế, nhưng hãy hỏi bất kỳ đồng nghiệp cao cấp nào của bạn để được tư vấn. Nếu bạn có 25.000 lỗi, bạn không sửa lỗi, bạn sửa những gì gây ra lỗi. Và một đồng nghiệp cao cấp sẽ có thể tư vấn cho bạn cách thực hiện thay đổi mà sếp của bạn muốn mà không có 25.000 lỗi liên quan. Có nhiều cách khác nhau để làm điều này, nhưng cách tốt là gì phụ thuộc vào tình huống cụ thể của bạn.

Và có thể ông chủ đã nói với các đồng nghiệp cấp cao của bạn thực hiện thay đổi tương tự, và họ nói "không". Bởi vì họ biết những gì sẽ xảy ra. Đó là lý do tại sao bạn được giao việc.


2
Đây chắc chắn là một điều quan trọng cần ghi nhớ. Nếu một nhân viên mới thực sự có tham vọng ở mức độ lớn, họ có thể cần cù (cả tin) để thực hiện nhiệm vụ thực sự lớn mà cuối cùng chỉ đạt được lợi thế bộ nhớ 5 byte hoặc logic hơn một chút để mã hóa và duy trì sau này.
Vịt lớn

@TheGreatDuck: Hãy cho tôi biết bạn chưa bao giờ thấy một giao diện được sử dụng ở mọi nơi và sai ở mọi nơi. Tôi chắc chắn có.
Joshua

@Joshua thậm chí không liên quan đến những gì tôi vừa nói. Đôi khi đã sửa một lỗi nhỏ không phải lúc nào cũng là ý tưởng thông minh nhất có nghĩa là viết lại hơn 10.000 dòng mã. Thật không may, một nhân viên mới có thể đủ tin tưởng để kéo 10 người suốt đêm bên ngoài công việc viết lại mã đó để gây ấn tượng với sếp của họ và hoàn thành nó. Chắc chắn, đó là một điều tuyệt vời để làm, nhưng đôi khi đủ là đủ. Bạn chỉ cần chấp nhận sự tồn tại của lỗi.
Vịt lớn

1
@Joshua btw, tôi chỉ tham gia cộng đồng này vì câu hỏi này xuất hiện trong nguồn cấp dữ liệu câu hỏi phổ biến của tôi. Tôi không có kinh nghiệm với thiết kế quy mô lớn như thế này. Tôi chỉ đồng ý với quan điểm của người này.
Vịt lớn

22

API cố thủ không thể thay đổi đơn giản. Nếu bạn thực sự cần thay đổi chúng, hãy khởi động và / hoặc ghi lại chúng là không dùng nữa (bằng bất cứ phương tiện nào mà ngôn ngữ cho phép) và thay vào đó nên sử dụng API nào. API cũ sau đó có thể được loại bỏ dần ... có lẽ rất chậm tùy thuộc vào ngân sách thời gian của bạn để tái cấu trúc.


10

Đánh giá

Đánh giá xem sự thay đổi này là cần thiết hay liệu bạn có thể thêm một phương pháp mới và không dùng phương pháp khác.

Ở đằng trước

Nếu thay đổi là cần thiết; sau đó một kế hoạch di chuyển là cần thiết.

Bước đầu tiên là giới thiệu phương thức mới và phương thức cũ xoa bóp các đối số của nó để nó có thể gọi phương thức mới. Điều này có thể yêu cầu mã hóa cứng một vài thứ; Tốt rồi.

Đây là một điểm cam kết: kiểm tra xem tất cả các bài kiểm tra vượt qua, cam kết, đẩy.

Di cư

Công việc bận rộn đang chuyển tất cả những người gọi phương thức cũ sang phương thức mới. Rất may nó có thể được thực hiện dần dần nhờ người giao nhận.

Vậy thì cứ đi; đừng ngần ngại sử dụng các công cụ để hỗ trợ ( sedlà cơ bản nhất, có những công cụ khác).

Đánh dấu phương thức cũ là không dùng nữa (với gợi ý chuyển sang phương thức mới); nó sẽ giúp bạn phát hiện xem bạn có quên bất cứ điều gì không và sẽ giúp ích nếu đồng nghiệp giới thiệu một cuộc gọi đến phương thức cũ trong khi bạn đang thực hiện việc này.

Đây là một điểm cam kết (hoặc có thể một vài điểm cam kết): kiểm tra xem tất cả các bài kiểm tra vượt qua, cam kết, đẩy.

Tẩy

Sau một thời gian trôi qua (có thể chỉ là một ngày), chỉ cần xóa phương thức cũ.


4
sedcó lẽ là một ý tưởng tồi ... Một cái gì đó thực sự "hiểu" ngôn ngữ và sẽ không tạo ra những thay đổi mạnh mẽ ngoài ý muốn là tốt hơn.
wizzwizz4

1
@ wizzwizz4: Thật không may, tôi đã tìm thấy rất ít công cụ thực sự hiểu ngôn ngữ đủ tốt cho C ++; hầu hết các công cụ dường như phục vụ cho việc đổi tên và đó là nó. Cấp, chỉ đổi tên các cuộc gọi phương thức chính xác (và không có bất kỳ cuộc gọi phương thức quá tải hoặc không liên quan nhưng có tên tương tự) đã rất ấn tượng, nhưng nó không đủ cho bất cứ điều gì phức tạp hơn. Ít nhất, bạn sẽ cần các khả năng để (1) xáo trộn các đối số, (2) áp dụng một phép biến đổi cho một đối số đã cho ( .c_str()ví dụ gọi ) và giới thiệu các đối số mới. sedkinda hoạt động, trình biên dịch nắm bắt các vấn đề của nó sau đó.
Matthieu M.

1
sed(hoặc ed) thể phù hợp với loại điều này - miễn là bạn xem xét chính xác các khác biệt trước khi bạn cam kết.
Toby Speight

Đây là TCRR của html, phải không? :)
Daniel Springer

8

Nếu thay đổi của bạn đối với chữ ký phương thức chỉ là thay đổi tên, thì giải pháp đơn giản là sử dụng các công cụ để tự động hóa thay đổi trong 25.000 lớp tham chiếu phương thức được đề cập.

Tôi giả sử rằng bạn chỉ đơn giản là chỉnh sửa mã theo cách thủ công, điều này đã dẫn đến tất cả các lỗi. Tôi cũng giả sử rằng bạn quen thuộc với Java (xem tài liệu tham khảo của bạn về OSGi), ví dụ như trong Eclipse (Tôi không biết bạn sử dụng môi trường lập trình nào, nhưng các môi trường khác có các công cụ tái cấu trúc tương tự) bạn có thể sử dụng "Tái cấu trúc -> Đổi tên" để cập nhật tất cả các tham chiếu đến phương thức, điều này sẽ khiến bạn không có lỗi.

Trong trường hợp bạn đang thực hiện các thay đổi khác đối với chữ ký phương thức thay vì chỉ đổi tên (thay đổi số lượng hoặc loại tham số), bạn có thể sử dụng "Tái cấu trúc -> Thay đổi chữ ký phương thức". Tuy nhiên, rất có thể bạn sẽ phải cẩn thận hơn như những câu trả lời khác gợi ý. Ngoài ra, bất kể loại thay đổi nào, nó vẫn có thể là một nhiệm vụ cam kết tất cả những thay đổi đó trong một cơ sở mã bận rộn.


2
OP đặc biệt nói OSGi là công việc trước đây của họ, vì vậy nó không thực sự phù hợp ở đây.
một CVn

3
@ MichaelKjorling Nếu OP là một lập trình viên Java trong công việc trước đây của họ, có một cơ hội tốt hơn là họ sẽ là một lập trình viên Java trong công việc này.
Giàu

@ MichaelKjorling Tôi muốn đưa ra một khuyến nghị cụ thể, sử dụng Eclipse để tái cấu trúc vì OP đã quen thuộc với Java. Liệu OP thực tế có sử dụng Java cho dự án hiện tại hay không, tôi đoán, ít quan trọng hơn, nhưng tôi nên làm rõ câu trả lời của mình. Cảm ơn.
MikkelRJ

6

Đây là đóng góp của tôi.

Gần đây tôi đã bắt đầu một công việc mới, nơi tôi đang làm việc trên một ứng dụng rất lớn (15M dòng mã).

Bạn có thể không quen thuộc với dự án và "tính năng" của nó. Trước khi nhập một dòng mã, điều quan trọng là phải làm quen với dự án. Vì vậy, hãy khôi phục các thay đổi của bạn và bắt đầu bằng cách phân tích mã . (Ít nhất là người bị ảnh hưởng)

Hiểu các giải pháp hiện có cung cấp cho bạn một viễn cảnh tốt hơn về nơi bạn đang bước vào. Bối cảnh các giải pháp và tầm quan trọng của nó.

Như @Greg đã chỉ ra, bạn sẽ có thể kiểm tra mã hiện có để có một tham chiếu hợp lệ để so sánh với (kiểm tra hồi quy). Giải pháp của bạn phải có khả năng tạo ra kết quả rất giống với kết quả hiện có. Ở giai đoạn này, bạn không quan tâm đến việc liệu kết quả có đúng hay không . Mục tiêu đầu tiên là tái cấu trúc, không sửa lỗi. Nếu giải pháp hiện tại cho biết "2 + 2 = 42", giải pháp của bạn cũng vậy. Nếu nó không ném ngoại lệ, thì bạn cũng không nên. Nếu nó trả về null, bạn cũng sẽ trả về null. Và như vậy. Nếu không, bạn sẽ thỏa hiệp 25k dòng mã.

Điều này là vì lợi ích của tính tương thích retro.

Tại sao? Bởi vì ngay bây giờ, đó là sự đảm bảo duy nhất của bạn về một nhà tái cấu trúc thành công.

Và nhiều bài kiểm tra đơn vị tham chiếu trực tiếp giao diện đó hoặc được ghép nối với các lớp cơ sở tham chiếu giao diện đó.

Một cách để đảm bảo tính tương thích retro là rất cần thiết cho bạn Vì vậy, đây là thử thách đầu tiên của bạn. Cô lập thành phần để thử nghiệm đơn vị.

Hãy nhớ rằng những dòng mã 25k đó đã được thực hiện với giả định kết quả có thể có của mã hiện có. Nếu bạn không phá vỡ phần này của hợp đồng, thì bạn đã đi được một nửa đến giải pháp cuối cùng. Nếu bạn làm, tốt: có thể lực lượng sẽ được với bạn

Khi bạn đã thiết kế và thực hiện "hợp đồng" mới, hãy thay thế hợp đồng cũ. Khấu hao nó hoặc lấy nó ra

Tôi đã đề nghị để lại các lỗi một mình vì tái cấu trúc và sửa lỗi là các nhiệm vụ khác nhau. Nếu bạn cố gắng đưa họ về phía trước cùng nhau, bạn có thể thất bại trên cả hai. Bạn có thể nghĩ rằng bạn đã tìm thấy lỗi, tuy nhiên, chúng có thể là "tính năng". Vì vậy, để chúng một mình (trong một phút).

25k dòng mã dường như đủ cho tôi các vấn đề để khiến tôi chỉ tập trung vào một nhiệm vụ.

Khi nhiệm vụ đầu tiên của bạn được thực hiện. Đưa ra những lỗi / tính năng cho ông chủ của bạn.

Cuối cùng, như @Stephen đã nói:

Bạn không thể làm gì nhiều về điều đó ngoại trừ làm cho mọi thứ tốt hơn. Khi bạn tạo các lớp mới, hãy đảm bảo rằng bạn đã kiểm tra chúng đúng cách và tạo chúng bằng các nguyên tắc RẮN để chúng sẽ dễ dàng thay đổi hơn trong tương lai


5

Kiểm tra nó

Mọi người khác đang đề xuất làm thế nào để tái cấu trúc để có ít tác động. Nhưng với nhiều lỗi đó, ngay cả khi bạn thành công trong việc tái cấu trúc với ít nhất 10 dòng mã (bạn có thể có thể), thì bạn đã tác động đến 25.000 luồng mã , ngay cả khi bạn không cần phải viết lại chúng.

Vì vậy, điều tiếp theo cần làm là đảm bảo bộ kiểm tra hồi quy của bạn vượt qua với màu sắc bay. Và nếu bạn không có, thì hãy làm một cái. Thêm bộ kiểm tra hồi quy toàn diện vào dự án nguyên khối của bạn nghe có vẻ nhàm chán nhưng là một cách hay để tăng sự tự tin trong các ứng cử viên phát hành, cũng như giải phóng chúng nhanh hơn nếu bộ được tự động hóa tốt.

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.