Tại sao sao chép và dán mã của mã nguy hiểm? [đóng cửa]


130

Đôi khi, ông chủ của tôi sẽ phàn nàn với chúng tôi:

Tại sao chúng ta cần một thời gian dài như vậy để thực hiện một tính năng?

Trên thực tế, tính năng này đã được triển khai trong một ứng dụng khác trước đây, bạn chỉ cần sao chép và dán mã từ đó. Chi phí phải thấp.

Đây thực sự là một câu hỏi khó, bởi vì sao chép và dán mã không phải là một điều đơn giản như vậy theo quan điểm của tôi.

Bạn có bất kỳ lý do tốt để giải thích điều này với ông chủ phi kỹ thuật của bạn?


19
nó giống như âm thanh thay vì sao chép và dán mã từ các ứng dụng trước của bạn sang một ứng dụng mới, bạn đang viết lại cùng một chức năng. Tôi nghĩ rằng nguyên tắc DRY hướng đến việc không có cùng chức năng được nhân đôi trong toàn bộ hệ thống, nhưng sử dụng lại mã từ các ứng dụng khác tốt hơn là viết lại nó.
Carson Myers

5
Bởi vì mỗi khi bạn sao chép và dán mã, một con dấu con sẽ bị giết.
DeadlyChambers

@CarsonMyer Chỉ khi thành phần có thể tái sử dụng. Và nó có nghĩa là để phù hợp với bối cảnh hiện tại.
Saletanth Karumanaghat

Câu trả lời:


171

Nếu bạn tìm thấy một lỗi trong mã sao chép-dán của mình, bạn sẽ cần sửa nó ở mọi nơi bạn đã làm và hy vọng bạn có thể nhớ tất cả chúng (điều này cũng đúng với các yêu cầu đã thay đổi).

Nếu bạn giữ logic ở một nơi, sẽ dễ thay đổi hơn khi cần (vì vậy nếu bạn quyết định rằng ứng dụng cần cập nhật, bạn chỉ thực hiện ở một nơi).

Nhờ sếp đọc về nguyên tắc DRY (Đừng lặp lại chính mình).

Những gì bạn đang mô tả âm thanh như việc sử dụng hoàn hảo cho các thư viện , nơi bạn chia sẻ mã và chỉ giữ nó ở một nơi.

Tôi sẽ chỉ sao chép mã dán nếu tôi định tái cấu trúc mã ngay sau đó - đảm bảo sau này tôi đã trích xuất mã chung để tôi có thể sử dụng lại càng nhiều logic càng tốt. Và ngay sau đó, tôi có nghĩa là phút và giờ sau đó, không phải ngày và tuần.


41
+1. Vấn đề là sao chép và dán rẻ tiền để giải quyết vấn đề trước mắt. Vấn đề thực sự là trong trung hạn / dài hạn, chi phí duy trì mã trùng lặp cao hơn nhiều so với mã được chứng thực tốt
Paolo

7
Đây không chỉ là một vấn đề lỗi; yêu cầu chương trình có thể thay đổi. Tôi đã thay đổi bốn trong số năm nơi cần thay đổi điều gì đó trước đây.
David Thornley

1
Nếu bạn có thể sao chép-dán theo yêu cầu và theo dõi các bản sao dễ dàng để sau đó trừu tượng hóa chúng hoặc cập nhật chúng, thì sao chép và dán không phải là điều xấu. Xem thảo luận về phát hiện bản sao tại www.semanticdesigns.com/ Products / Clone để biết thêm chi tiết và các công cụ hơn có thể làm điều này.
Ira Baxter

4
Có rất nhiều ifs, và hầu hết các công cụ không hỗ trợ phát hiện bản sao vào thời điểm này.
Oded

2
Ngày xửa ngày xưa có một lập trình viên làm việc cho ESA . Ông đang làm việc trên phần mềm cho tên lửa Ariane-5 và ông đã sử dụng phương pháp sao chép-dán. Sau đó , ... xảy ra
Hauleth

25

Bạn sẽ tốt hơn nhiều khi chia sẻ mã bằng cách xây dựng thư viện thay vì sao chép mã bằng cách sao chép và dán.

Bạn vẫn sẽ đạt được lợi thế về tốc độ so với việc viết lại (tra cứu DRY) nhưng sẽ chỉ có một nơi để duy trì mã.


1
Tôi chỉ tò mò, tại sao bạn lại "cắt" mã nếu tất cả những gì bạn cần làm là sao chép nó?
dpp

Điểm tốt dpp. Đã chỉnh sửa!
CResults

12

Lý do rõ ràng là bạn sẽ nhận một 'khoản nợ' cho tương lai: mọi thay đổi bạn cần thực hiện trong mã (không chỉ là lỗi, bất kỳ thay đổi nào) sẽ tốn kém gấp đôi vì bạn phải cập nhật hai nơi - và rủi ro hơn vì cuối cùng bạn sẽ quên một trong số họ. Nói cách khác, làm cho nó hoạt động nhanh hơn bây giờ sẽ làm cho công việc của bạn thậm chí chậm hơn trong tương lai, điều này thể có ý nghĩa kinh doanh tốt nhưng thường thì không.

Nhưng lý do quan trọng hơn là giả định "điều này giống như vậy" thường không sai một cách tinh vi. Bất cứ khi nào mã của bạn phụ thuộc vào các giả định bất thành văn là chính xác, việc sao chép mã vào một nơi khác sẽ dẫn đến lỗi trừ khi các giả định này cũng được giữ ở vị trí mới. Do đó, mã đã dán thường sai từ đầu và không chỉ sau lần thay đổi tiếp theo.


11

Thiết kế mã, sao chép mã dán chắc chắn là một thảm họa, với khả năng gây ra nhiều vấn đề trong tương lai. Nhưng bạn đang hỏi tại sao phải mất rất nhiều công việc ngay bây giờ , câu trả lời là: bởi vì nó không bao giờ chỉ là sao chép và dán.

Nếu mã gốc được viết để sử dụng lại, như một thư viện khá độc lập, có tính linh hoạt và sử dụng máy khách - thì thật tuyệt, nhưng đó không phải là sao chép, đó là sử dụng thư viện mã. Dán sao chép mã thực thường giống như thế này:

  • "Chắc chắn, tôi đã có mã thực hiện chính xác điều đó!"
  • "Đợi đã, phiên bản nào trong năm phiên bản mã này là phiên bản tôi muốn sử dụng làm nguồn của mình?"
  • "Hmmm, tất cả các chức năng 'produc_func_023' này làm gì? Tôi không có tài liệu cho họ sao? Bây giờ tôi cần cái nào?"
  • "Ồ, vâng, mã này sử dụng Mã cơ sở Y. Đoán tôi cần [ chọn một: sao chép tất cả Mã cơ sở Y vào dự án mới của tôi / dành một ngày để trích xuất một chức năng tôi muốn từ Mã cơ sở Y / dành một tuần để giải mã một chức năng tôi muốn từ Mã cơ sở Y]. "
  • "Tôi đã sao chép mọi thứ, yay!"
  • "Tại sao điều này không hoạt động?"
  • Đây là điểm mà bạn dành hàng giờ / ngày / tuần để gỡ lỗi mã hiện có tương tự như những gì bạn muốn, thay vì viết mã bạn thực sự muốn bắt đầu.

Tóm lại, mã hiện tại không thể được sử dụng trực tiếp có thể, tốt nhất, đóng vai trò là tài liệu tham khảo tốt để viết mã tương tự. Nó chắc chắn không thể được nâng toàn bộ và dự kiến ​​sẽ hoạt động trong một hệ thống hoàn toàn khác. Nói chung, đó là một giả định an toàn rằng bất kỳ mã nào đã được viết và hoàn thành, nên được gửi càng ít càng tốt - ngay cả khi đó là bản sao chứ không phải bản gốc.

Nếu bạn muốn dựa trên dự án của mình để dán sao chép, bạn phải bắt đầu mã theo cách cho phép tái sử dụng dễ dàng, mà không sao chép mã gốc đó và làm rối tung nó. Điều đó đáng để làm, và nếu đó là điều mà sếp của bạn đang mong đợi, thì cả hai bạn cần chắc chắn rằng đó là cách bạn thiết kế và làm việc ngay từ đầu.


9

sao chép và dán là một thảm họa đang chờ để xảy ra. Sếp của bạn nên đánh giá giá vận chuyển sớm liên quan đến giá của việc mã bị hỏng được chuyển đến người dùng cuối rất sớm.


9

Nếu bạn đã thực hiện các tính năng và bạn cần sao chép và dán để sử dụng lại chúng, có vẻ như bạn đã làm sai điều gì đó. Bạn không thể đặt các tính năng này trong thư viện để bạn có thể sử dụng lại chúng mà không cần sao chép / dán?


8

Nguyên tắc DRY (Đừng lặp lại chính mình): DRY trên wikipedia .

"Mỗi phần kiến ​​thức phải có một đại diện duy nhất, rõ ràng, có thẩm quyền trong một hệ thống."

liên kết khác .


Điều này giống như nói, "không bao giờ cắm dao vào cổ người đàn ông", nghe có vẻ như là một quy tắc rất tốt. Cho đến khi bạn nhận ra rằng bác sĩ PHẢI phá vỡ quy tắc này để thực hiện phẫu thuật cắt bỏ để cứu sống một người đàn ông (nếu anh ta không thể thở, có lẽ do sốc phản vệ, phản ứng dị ứng cực độ). Mọi quy tắc đều có một ngoại lệ (ngoại trừ, có lẽ, đối với quy tắc này - rằng mọi quy tắc đều có ngoại lệ). Do đó, mọi quy tắc phải có lý do và danh sách các trường hợp ngoại lệ và thời điểm, tất cả được đính kèm, đối với thực tế "kỹ thuật" thực sự mà câu trả lời thực sự là, nó phụ thuộc ...
microserviceOnDĐD

Vậy ... khi nào bạn KHÔNG theo dõi KHÔ? Tôi liên tục vật lộn với điều này trong công việc hiện tại của tôi, liên quan đến phần sụn và câu trả lời là chúng tôi "bỏ vòng lặp" và làm những việc khác vì điều đó "cải thiện hiệu suất". Chúng tôi có một hệ thống phân cấp thừa kế rất nông và chúng tôi sử dụng hầu hết các lớp trực tiếp thay vì phân lớp chúng và ... ... chúng tôi sử dụng sao chép và dán rất nhiều. Và tôi ghét nó, bởi vì nó làm cho cơ sở mã của chúng tôi khó hiểu hơn và khó bảo trì hơn. Nhưng chúng tôi có lý do của chúng tôi, và chúng là lý do chấp nhận được. Chúng tôi không phải là các bên liên quan duy nhất. Và tìm sự cân bằng phù hợp là một nghệ thuật.
microsOnOnD

7

Đối với tôi có vẻ như quan niệm sai lầm tồi tệ nhất của ông chủ phi kỹ thuật của bạn, đó là công việc của bạn chủ yếu là đánh máy. Họ nghĩ rằng bạn có thể tiết kiệm rất nhiều thời gian bằng cách loại bỏ việc gõ.

Tôi nghĩ rằng nền giáo dục tốt nhất bạn có thể cung cấp cho người này là chỉ ra tất cả những công việc bạn làm không phải là đánh máy. Ngay cả khi hầu hết công việc đó thường xảy ra vô hình, trong đầu bạn, cùng lúc với việc gõ.

Chắc chắn, loại bỏ việc gõ sẽ tiết kiệm thời gian. Nhưng sau đó, phần lớn hơn, không gõ, một phần công việc của bạn trở nên lớn hơn và ăn bất kỳ thời gian tiết kiệm và nhiều hơn nữa bên cạnh.


4

Bạn có chắc rằng sếp của bạn muốn nghe về nguyên tắc DRY, lỗi và các thứ công nghệ khác?

Đó là những bình luận bạn thường nghe khi sếp hoặc công ty đánh giá thấp thời gian cần thiết để hoàn thành một số dự án. Và dựa trên ước tính sai, một hợp đồng đã được ký, v.v. Trong hầu hết các trường hợp, các lập trình viên không tham gia vào các ước tính.

Tại sao điều này xảy ra? Đôi khi nhà tài trợ dự án có ngân sách quá nhỏ. Có thể một quy trình kinh doanh mà bạn đang tự động hóa bằng phần mềm không đáng để bạn nỗ lực. Các nhà quản lý thường có xu hướng rất kín vì tin xấu trong những trường hợp như vậy. Khi bắt đầu dự án có mơ tưởng. Sau đó, các nhà quản lý cố gắng đổ lỗi cho các lập trình viên. Trong trường hợp của bạn gián tiếp thông qua sao chép và dán. Trong trường hợp cực đoan, điều này được gọi là một cuộc tuần hành tử thần .


3

Sao chép và dán mã thường dẫn đến Lập trình bởi sự trùng hợp


Tôi thấy bài viết này đặc biệt viết xấu. Câu chuyện kể vẫn trừu tượng do đó không làm sáng tỏ vụ án ngoài thực tế là Fred đang làm việc lặp đi lặp lại. Một vấn đề rõ ràng Fred có là anh ta không có ý tưởng tốt về kiến ​​trúc tổng thể. Thật không may, điều này rất thường xảy ra khi chúng tôi làm việc với mã kế thừa không có giấy tờ nơi bí quyết bị mất. Tài liệu tham khảo về Thiết kế theo Hợp đồng và Lập trình quyết đoán là khá tốt, nhưng thật không may, ngay cả sau khi các ví dụ / bài tập vẫn không giải thích được.
mapto

3

Tôi nghĩ rằng " ứng dụng khác " là chìa khóa ở đây, nếu ứng dụng khác đã được thử nghiệm và đang sử dụng, thì không nên thay đổi nó để sử dụng một thư viện chung, do đó bạn không thể chia sẻ mã với nó.

Trong cùng một ứng dụng , sao chép và dán bản sao là xấu, nhưng giữa các cơ sở mã được phát triển bởi các nhóm khác nhau hoặc với các chu kỳ phát hành khác nhau, bản sao và dán dán có thể là lựa chọn tốt nhất.


Mặc dù tôi có thể thấy rằng có rất ít điểm trong việc phát hành bản cập nhật cho ứng dụng khác chỉ để sử dụng thư viện, nhưng có lẽ sẽ là một ý tưởng tốt để ít nhất tạo ra một cú đâm vào những thay đổi cần thiết trong nhánh tính năng. Điều này sẽ cho bạn một chút tin tưởng rằng giao diện của thư viện đủ chung cho ít nhất hai ứng dụng được đề cập và cho phép bạn hợp nhất thay đổi tại một điểm thích hợp trong chu kỳ phát hành.
SamB

2

Tôi làm việc cho một công ty tương tự. Trở thành thực tập sinh, sau đó tôi không biết rõ hơn, vì vậy khi tôi bắt đầu một dự án mới, sếp của tôi cũng đề nghị dán mã từ một nơi khác. Vâng, như bạn có thể nghĩ, toàn bộ phần mềm là một mớ hỗn độn, đến mức khi bạn cố gắng sửa một lỗi, hai lỗi mới xuất hiện.


2

Ngay cả khi ứng dụng khác đã có tính năng bạn cần, mã cho tính năng đó có thể không phù hợp với ứng dụng hiện tại của bạn mà không cần viết lại chính. Nó giống như lấy động cơ của một chiếc Ford và cố gắng lắp nó vào một chiếc Toyota. Nói chung, có một nguyên tắc nhỏ là nếu bạn phải sửa đổi hơn 25% mã bạn sao chép, tốt hơn (rẻ hơn) để viết lại từ đầu.

Trích xuất mã trong câu hỏi vào thư viện nghe có vẻ hấp dẫn, nhưng nó có thể khó hơn âm thanh, tùy thuộc vào cách hệ thống khác được xây dựng. Ví dụ: mã cho tính năng đó có thể khó trích xuất vì nó giao tiếp với rất nhiều mã khác theo những cách ô uế (ví dụ: bằng cách truy cập nhiều biến toàn cục, v.v.)


1

Nói với sếp của bạn rằng một phần của mỗi tên biến bao gồm tên của dự án cũ và bây giờ bạn phải thay đổi tất cả bằng tay. Nếu sếp của bạn không biết (hoặc muốn biết) tại sao sao chép / dán là xấu thì anh ấy / cô ấy cũng có thể tin rằng :)


1

Vâng, vấn đề lớn nhất là nó không chỉ sao chép và dán - bản sao của nó sau đó dán rồi sửa đổi một chút.

Sau đó, khi một trong những biến thể được dán có vấn đề, nó sẽ được thay đổi. Sau đó, một biến thể khác được thay đổi.

Sau đó, bạn phát hiện ra rằng tất cả các biến thể phải thay đổi khiến bản sao gốc có lỗi. Bây giờ bạn đã ổn và thực sự say mê vì tất cả các khu vực dán bây giờ không giống nhau.

Và bạn sẽ không biết điều đó, loại mã hóa nhảm nhí này thường gần như hoàn toàn không có ý kiến.

Đối với tôi, sự khác biệt là khi bạn có nhiều bản sao mã làm cùng một việc, thứ bạn có là một loạt mã. Khi bạn chỉ có một đoạn mã làm từng việc cụ thể, thì bạn có một hệ thống.

Hành vi của một hệ thống có thể được thay đổi với các sửa đổi điểm đơn khá dễ dàng - thay đổi hành vi của một nhóm mã yêu cầu một loạt mã.

Tôi thích các hệ thống, không phải là một loạt các mã.


1

Có sự đánh đổi giữa tốc độ phát triển của chức năng ngay lập tức trước mặt bạn (đặc biệt là khi ứng dụng còn nhỏ) và chi phí bảo trì dài hạn khi ứng dụng phát triển.

Sao chép và dán nhanh hơn cho chức năng ngay lập tức, nhưng sẽ khiến bạn phải trả giá đắt khi ứng dụng tăng kích thước, về mặt sửa lỗi và thực hiện thay đổi toàn hệ thống và duy trì quy trình làm việc giữa các thành phần khác nhau của ứng dụng.

Đó là lập luận mà chủ doanh nghiệp cần nghe. Nó tương tự như chi phí được chấp nhận để duy trì một đội xe, tuy nhiên, với phần mềm, các khía cạnh bị hỏng của kiến ​​trúc phần mềm thường được ẩn cho phía doanh nghiệp và chỉ có thể được các nhà phát triển nhìn thấy.


0

Anh ta nói đúng rằng nếu nhóm đã thực hiện chức năng tương tự trước đó, việc lặp lại sẽ dễ dàng hơn nhiều lần thứ 2.

Tuy nhiên, có lẽ bạn nên giải thích rằng mỗi ứng dụng là khác nhau. Chỉ vì bạn đã cài đặt một cánh cửa trong một ngôi nhà không có nghĩa là bạn có thể cài đặt một cánh cửa khác trong một ngôi nhà khác trong thời gian không bằng phẳng - bạn sẽ nhanh hơn vì có kinh nghiệm (# cửa được cài đặt), nhưng vẫn sẽ mất thời gian để có được thiết bị cho bạn , gắn cửa, đảm bảo nó thẳng đứng và vặn nó vào khung.


0

trong công ty của tôi, chúng tôi luôn làm việc với các lớp và phương pháp, và làm tài liệu kỹ thuật cho họ. Tôi nghĩ rằng đó là cách thực hành tốt nhất nếu bạn có thể sử dụng các ứng dụng tìm kiếm svn của riêng bạn với các khóa tốt để tìm lớp phương thức được sử dụng trước đó :)

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.