Là ngu ngốc để có năng suất tốt hơn?


112

Tôi đã dành rất nhiều thời gian để đọc các cuốn sách khác nhau về "thiết kế tốt", "mẫu thiết kế", v.v. Tôi là một fan hâm mộ lớn của phương pháp RẮN và mỗi khi tôi cần viết một đoạn mã đơn giản, tôi nghĩ về tương lai. Vì vậy, nếu triển khai một tính năng mới hoặc sửa lỗi yêu cầu chỉ cần thêm ba dòng mã như thế này:

if(xxx) {
    doSomething();
}

Điều đó không có nghĩa là tôi sẽ làm theo cách này. Nếu tôi cảm thấy đoạn mã này có khả năng trở nên lớn hơn trong tương lai gần nhất, tôi sẽ nghĩ đến việc thêm trừu tượng, di chuyển chức năng này sang một nơi khác và cứ thế. Mục tiêu tôi đang theo đuổi là giữ độ phức tạp trung bình giống như trước khi tôi thay đổi.

Tôi tin rằng, từ quan điểm mã, đó là một ý tưởng khá hay - mã của tôi không bao giờ đủ dài và khá dễ hiểu ý nghĩa của các thực thể khác nhau, như các lớp, phương thức và quan hệ giữa các lớp và các đối tượng.

Vấn đề là, nó tốn quá nhiều thời gian và tôi thường cảm thấy sẽ tốt hơn nếu tôi chỉ thực hiện tính năng đó "như hiện tại". Đó chỉ là về "ba dòng mã" so với "giao diện mới + hai lớp để thực hiện giao diện đó".

Từ quan điểm sản phẩm (khi chúng ta nói về kết quả ), những điều tôi làm là khá vô nghĩa. Tôi biết rằng nếu chúng ta sẽ làm việc trên phiên bản tiếp theo, có mã tốt thực sự rất tuyệt. Nhưng mặt khác, thời gian bạn dành để làm cho mã của mình "tốt" có thể đã được dành cho việc triển khai một vài tính năng hữu ích.

Tôi thường cảm thấy rất không hài lòng với kết quả của mình - mã tốt chỉ có thể làm A còn tệ hơn mã xấu có thể làm A, B, C và D.

Cách tiếp cận này có khả năng dẫn đến lợi ích ròng tích cực cho một dự án phần mềm, hay nó là một sự lãng phí thời gian?


141
tôi sẽ thấy RẮN của bạn và rasie bạn YAGNI và KISS
jk.

16
Bùng nổ, headshot.
Robert S.

16
Vấn đề "kỹ thuật quá mức" đôi khi là biểu hiện của một quy trình nắm bắt yêu cầu không hoạt động đúng. Nếu bạn đang vật lộn với "what-if" và sau đó tự trả lời chúng mà KHÔNG CÓ sự tương tác của người nắm giữ cổ phần / khách hàng, điều đó sẽ đặt bạn vào vị trí dự đoán tương lai. Có lẽ lấy một số nỗ lực đó và đưa nó trở lại để hiểu các yêu cầu tốt hơn trước khi đưa ra sự phức tạp hơn vào mã?
Angelo

4
Có thể đó chỉ là tôi nhưng tôi sẽ xem xét "ngu ngốc" khi khiến khách hàng / chủ lao động của tôi tiêu tiền để có thứ mà họ không yêu cầu / muốn: S
Thomas Bonini

2
Hầu như không bao giờ khó hơn để thêm một tính năng trong tương lai khi nó thực sự cần thiết. Bạn không đạt được bất cứ điều gì bằng cách làm nó bây giờ.
Phần

Câu trả lời:


153

mã tốt chỉ có thể làm A còn tệ hơn mã xấu có thể làm A, B, C, D.

Điều này có mùi với tôi như chung chung đầu cơ . Không biết (hoặc ít nhất là chắc chắn hợp lý) rằng khách hàng của bạn sẽ cần các tính năng B, C và D, bạn chỉ cần thiết kế quá mức một cách không cần thiết. Mã phức tạp hơn khó hiểu và duy trì trong thời gian dài. Sự phức tạp thêm chỉ được chứng minh bằng các tính năng bổ sung hữu ích . Nhưng chúng ta thường rất tệ trong việc dự đoán tương lai. Hầu hết các tính năng chúng tôi nghĩ thể cần thiết trong tương lai sẽ không bao giờ được yêu cầu trong cuộc sống thực.

Vì thế:

Mã tốt chỉ có thể làm A (nhưng nó đang làm một điều đơn giản và gọn gàng) thì TỐT HƠN so với mã xấu có thể làm A, B, C, D (một số thể cần thiết trong tương lai).


87
+1 cho "chúng tôi thường rất tệ trong việc dự đoán tương lai" Người dùng rất có thể sẽ yêu cầu E :)
Michał Piaskowski

1
+1 Không thể đồng ý nhiều hơn. Gần đây tôi đã hoàn thành một nhiệm kỳ làm việc tại một công ty, và tôi sẽ coi đây là bài học quan trọng nhất tôi học được.
Wipqozn

4
@ Michał, đó có phải là một dự đoán? ;-)
Péter Török

10
Ngay cả khi họ hỏi bạn về D, họ có thể sẽ có một mô hình tinh thần khác về nó và sẽ yêu cầu một loại D hơi khác mà sự trừu tượng của bạn không hỗ trợ ...
Chris Burt-Brown

"Nếu một vấn đề chưa hoàn toàn được hiểu, có lẽ tốt nhất là không cung cấp giải pháp nào cả" hoặc "Không thêm chức năng mới trừ khi người triển khai không thể hoàn thành một ứng dụng thực sự mà không có nó." áp dụng tại đây. Qua en.wikipedia.org/wiki/X_Window_System#Principles
nwahmaet

87

Thời gian giai thoại:

Tôi đã có hai nhà phát triển làm việc cho tôi, người nghiêng về kỹ thuật quá mức theo cách này.

Đối với một trong số họ, điều này về cơ bản khiến năng suất của anh ta bị đình trệ, đặc biệt là khi bắt đầu một dự án mới. Đặc biệt nhất là nếu dự án, về bản chất, khá đơn giản. Cuối cùng, một phần mềm hoạt động bây giờ là thứ chúng ta cần. Điều này trở nên tồi tệ đến mức tôi phải để anh ấy đi.

Các nhà phát triển khác, những người có xu hướng kỹ thuật quá mức đã bù đắp cho nó bằng cách cực kỳ năng suất. Như vậy, mặc dù tất cả các mã ngoại lai, anh vẫn giao hàng nhanh hơn hầu hết. Tuy nhiên, bây giờ khi anh ấy tiếp tục, tôi thường cảm thấy khó chịu với số lượng công việc cần thiết để thêm chức năng khi bạn phải sửa đổi các lớp trừu tượng (hoàn toàn không cần thiết), v.v.

Vì vậy, đạo đức là, kỹ thuật quá mức sẽ ăn thêm thời gian có thể được chi tiêu tốt hơn để làm những việc hữu ích. Và không chỉ thời gian của riêng bạn, mà còn của những người phải làm việc với mã của bạn.

Vì vậy, không.

Bạn muốn mã của bạn đơn giản nhất có thể (và không đơn giản hơn). Xử lý 'maybes' không làm mọi thứ đơn giản hơn, nếu bạn đoán sai, bạn sẽ làm cho mã phức tạp hơn mà không có lợi ích thực sự để hiển thị cho nó.


10
+1 càng đơn giản càng tốt nhưng không đơn giản.
Julian

33
"Một nhà thiết kế biết rằng anh ta đã đạt được sự hoàn hảo không phải khi không còn gì để thêm, mà là khi không còn gì để lấy đi." Antoine de Saint-Exupery
Arkh

tránh trùng lặp như bệnh dịch hạch và bạn sẽ không đi quá xa.
Kevin

@arkh ... Tôi sẽ sử dụng cùng một trích dẫn: P
Michael Brown

6
Tôi sẽ đặt nó theo cách này: Mỗi dòng mã có chi phí cao liên quan đến nó. Vì vậy, giảm thiểu chi phí bằng cách giảm thiểu mã. Xóa mã không cần thiết là hiệu quả (thậm chí có thể hiệu quả hơn) so với viết mã mới.
Kristopher Johnson

26

Nguyên tắc RẮN và KISS / YAGNI là hai mặt đối lập gần như cực. Một người sẽ nói với bạn rằng nếu doS Something () không thể được coi là một phần không thể thiếu của công việc mà lớp gọi nó đang làm, thì nó phải ở trong một lớp khác được ghép và tiêm một cách lỏng lẻo. Người kia sẽ cho bạn biết rằng nếu đây là một nơi doS Something được sử dụng, thậm chí trích xuất nó thành một phương thức có thể đã quá mức cần thiết.

Đây là những gì làm cho các lập trình viên tốt có giá trị trọng lượng của họ bằng vàng. Cấu trúc "đúng" là cơ sở từng trường hợp cụ thể, đòi hỏi kiến ​​thức về cơ sở mã hiện tại, con đường tương lai của chương trình và nhu cầu của doanh nghiệp đằng sau chương trình.

Tôi thích làm theo phương pháp ba bước đơn giản này.

  • Trên đường chuyền đầu tiên, làm cho nó hoạt động.
  • Trên đường chuyền thứ hai, làm cho nó sạch sẽ.
  • Trên đường chuyền thứ ba, làm cho nó RẮN.

Về cơ bản, đây là cách bạn pha trộn KISS với RẮN. Khi bạn lần đầu tiên viết một dòng mã, đối với tất cả những gì bạn biết, nó sẽ là một lần; nó chỉ đơn giản là phải làm việc và không ai quan tâm làm thế nào, vì vậy đừng có thích. Lần thứ hai bạn đặt con trỏ vào dòng mã đó, bạn đã từ chối giả thuyết ban đầu của mình; khi xem lại mã này, bạn có khả năng mở rộng nó hoặc móc vào nó từ một nơi khác. Bây giờ, bạn nên làm sạch nó một chút; trích xuất các phương thức cho các mẩu tin thường được sử dụng, giảm hoặc loại bỏ mã hóa / dán sao chép, thêm một vài nhận xét, v.v ... Lần thứ ba bạn quay lại mã này, giờ đây là giao điểm chính cho các đường dẫn thực thi chương trình của bạn. Bây giờ bạn nên coi nó như một phần cốt lõi của chương trình của mình và áp dụng các quy tắc RẮN khi khả thi.

Ví dụ: Bạn cần viết một dòng văn bản đơn giản vào bàn điều khiển. Lần đầu tiên điều này xảy ra, Console.WriteLine () vẫn ổn. Sau đó, bạn quay lại mã này sau khi các yêu cầu mới cũng ra lệnh viết cùng một dòng vào nhật ký đầu ra. Trong ví dụ đơn giản này, có thể không có nhiều mã "sao chép / dán" lặp đi lặp lại (hoặc có thể có), nhưng bạn vẫn có thể thực hiện một số dọn dẹp cơ bản, có thể trích xuất một hoặc hai phương thức để tránh đưa các hoạt động IO vào logic kinh doanh sâu hơn . Sau đó, bạn quay lại khi máy khách muốn cùng một đầu ra văn bản đến một ống có tên cho một máy chủ giám sát. Bây giờ, thói quen đầu ra này là một vấn đề lớn; bạn đang phát cùng một văn bản theo ba cách. Đây là ví dụ trong sách giáo khoa về thuật toán sẽ được hưởng lợi từ mẫu Tổng hợp; phát triển giao diện IWriter đơn giản với phương thức Write (), triển khai giao diện đó để tạo các lớp ConsoleWriter, FileWriter và NamedPipeWriter và một lần nữa để tạo một lớp tổng hợp "MultiWriter", sau đó hiển thị một phụ thuộc IWriter trên lớp của bạn, thiết lập hỗn hợp MultiWriter với ba người viết thực tế và cắm nó vào. Bây giờ, nó khá RẮN; từ thời điểm này trở đi, bất cứ khi nào các yêu cầu chỉ ra rằng đầu ra sẽ đi bất kỳ nơi nào mới, bạn chỉ cần tạo một IWriter mới và cắm nó vào MultiWriter, không cần phải chạm vào bất kỳ mã làm việc hiện có nào.


Đồng ý, nhưng thông thường một khi bạn vượt qua bước đầu tiên, bạn sẽ không bao giờ quay lại bước thứ hai hoặc thứ ba, vì bây giờ tính năng này là "trực tiếp" và có nhiều tính năng khác xuất hiện để bạn không thể quay lại và sửa tính năng đầu tiên. Bạn thấy rằng tất cả những gì bạn có thể làm là bước đầu tiên với mọi tính năng và sau đó bạn bị bỏ lại với một đầm lầy.
Wayne Molina

2
@Wayne M - Nó chắc chắn có thể xảy ra theo cách đó trong thác SDLC hoặc trong các tình huống ngắn. Trong những trường hợp đó, hoàn thành công việc theo thông số kỹ thuật ban đầu trước hạn chót là những gì đang được định giá, không phải là khả năng duy trì của mã. Nếu bạn muốn định giá chất lượng của mã nguồn, bạn chỉ cần xây dựng thời gian vào lịch trình để tái cấu trúc. Giống như nếu bạn coi trọng chất lượng nội dung trong bất kỳ công việc nào khác liên quan đến sản xuất thông tin bằng văn bản, bạn sẽ dành thời gian để kiểm chứng và chỉnh sửa.
KeithS

Dòng mở đầu của bạn là sai lệch - bạn nói rằng họ phản đối, sau đó mô tả cách tốt nhất để sử dụng chúng cùng nhau. Tôi không biết liệu tôi nên downvote cho dòng xấu hay upvote cho lời khuyên tốt.
Sean McMillan

1
Tôi không nghĩ rằng tôi mâu thuẫn với chính mình. Họ là những đối lập gần cực; Tuân thủ tôn giáo với người này hay người kia nhất thiết sẽ có nghĩa là từ chối người kia. Tuy nhiên, điều đó không có nghĩa là chúng loại trừ lẫn nhau; bạn không phải chọn tuân thủ 100% theo một trong hai phương pháp. Đó là điểm của phần còn lại của câu trả lời; Làm thế nào để bạn đạt được sự cân bằng khi làm như vậy liên quan đến cho và nhận từ các kết luận của mỗi nguyên tắc?
KeithS

Quá trình thực sự tốt đẹp: công trình, sạch sẽ, RẮN. Tôi tự hỏi nếu một hệ quả của điều này là "đừng thử và thiết kế bất cứ thứ gì mà không có nguyên mẫu bị hack trước".
Steve Bennett

17

mã tốt chỉ có thể làm A còn tệ hơn mã xấu có thể làm A, B, C, D.

1) Có một mã chỉ làm những gì được cho là phải làm.

Nếu tôi cảm thấy đoạn mã này có khả năng trở nên lớn hơn trong tương lai gần nhất, tôi sẽ nghĩ đến việc thêm trừu tượng, di chuyển chức năng này sang một nơi khác và cứ thế.

2) Nếu bạn lập kế hoạch mã của bạn để làm A, B, C và D, cuối cùng khách hàng sẽ yêu cầu bạn cho E.

Mã của bạn nên làm những gì được cho là phải làm, bạn không nên nghĩ về việc triển khai trong tương lai, bởi vì bạn sẽ không bao giờ kết thúc việc thay đổi mã của mình liên tục và quan trọng hơn là bạn sẽ thiết kế quá mức mã của mình. Bạn nên cấu trúc lại mã của mình ngay khi bạn cảm thấy cần mã vì các tính năng hiện tại, không phải vật lộn để chuẩn bị cho thứ gì đó mà nó chưa làm, trừ khi bạn đã lên kế hoạch cho nó như là một phần của kiến ​​trúc dự án.

Tôi đề nghị bạn đọc một cuốn sách hay: Lập trình viên thực dụng . Nó sẽ mở mang đầu óc và dạy bạn những gì bạn nên làm và những gì bạn không nên làm.

Ngoài ra Code Complete là một nguồn tài nguyên tuyệt vời với đầy đủ các thông tin hữu ích mà mọi nhà phát triển (không chỉ lập trình viên) nên đọc.


12

rất cần thời gian tôi cần viết một đoạn mã đơn giản, tôi nghĩ về tương lai

Có lẽ đây là vấn đề.

Ở giai đoạn đầu, bạn không biết đâu sẽ là sản phẩm cuối cùng. Hoặc nếu bạn có nó, nó sai. Chắc chắn. Nó giống như một cậu bé 14 tuổi, người đã hỏi vài ngày trước về Lập trình viên. Nếu anh ta phải, trong sự nghiệp tương lai của mình, hãy chọn giữa các ứng dụng web và tôi không nhớ gì nữa: trong một vài năm, mọi thứ khá rõ ràng Anh ấy thích sẽ thay đổi, anh ấy sẽ được quan tâm bởi các lĩnh vực khác, vv

Nếu, để viết ba dòng mã, bạn tạo một giao diện mới và hai lớp, bạn quá kỹ thuật. Bạn sẽ có được một mã sẽ khó bảo trì và khó đọc , chỉ vì với mỗi dòng mã hữu ích, bạn có hai dòng mã bạn không cần. Không tính tài liệu XML, kiểm tra đơn vị, v.v.

Hãy suy nghĩ về điều này: nếu tôi muốn biết cách một tính năng được triển khai trong mã của bạn, tôi sẽ dễ dàng đọc qua hai mươi dòng mã hơn, hoặc sẽ nhanh hơn và dễ dàng hơn khi phải mở hàng chục lớp bán trống và giao diện để tìm ra cái nào sử dụng cái nào, chúng có liên quan như thế nào, v.v.?

Hãy nhớ rằng: codebase lớn hơn có nghĩa là bảo trì nhiều hơn. Đừng viết thêm mã khi bạn có thể tránh nó.

Cách tiếp cận của bạn cũng có hại ở các mặt khác:

  • Nếu bạn cần xóa một tính năng, không dễ dàng hơn để tìm ra phương pháp hai mươi dòng cụ thể được sử dụng, hơn là lãng phí thời gian của bạn để hiểu sự phụ thuộc giữa hàng tá lớp?

  • Khi gỡ lỗi, không dễ dàng hơn để có một dấu vết ngăn xếp nhỏ, hay bạn thích đọc hàng tá dòng để tìm ra cái gì được gọi bằng cái gì?

Để kết luận, nó có vẻ tương tự như tối ưu hóa sớm . Bạn đang cố gắng giải quyết vấn đề mà không chắc chắn liệu có vấn đề gì ở nơi đầu tiên không, và nó ở đâu. Khi làm việc trên phiên bản 1 của sản phẩm, hãy triển khai các tính năng bạn cần triển khai ngay bây giờ; đừng nghĩ về điều gì đó bạn muốn thực hiện trong hai năm ở phiên bản 14.


"Hàng tá các lớp bán trống" có nhược điểm bổ sung là không có đủ tài liệu để hiểu những lớp này tốt cho cái gì.
gnasher729

5

Viết nhiều mã sẽ (có thể) sẽ không bao giờ được sử dụng là một cách rất tốt để được cấp P45 . Bạn không có một quả cầu pha lê và không biết hướng đi cuối cùng là sự phát triển sẽ mất bao nhiêu thời gian cho các chức năng này chỉ tốn tiền cho việc không trả lại tiền.


3

Cố gắng dự đoán những gì có thể cần thiết từ mã trong tương lai thường kết thúc là không cần thiết quá kỹ thuật (một thói quen tôi hiện đang cố gắng bắt đầu). Tôi sẽ nói chỉ cần làm ba dòng. Khi có nhu cầu (và không phải trước đó), tái cấu trúc. Bằng cách đó, mã của bạn luôn làm những gì nó cần mà không quá phức tạp và phát triển cấu trúc tốt một cách tự nhiên thông qua tái cấu trúc.


3

Tôi thường nói rằng mã hóa giống như mặt sáng / mặt tối của Thần lực - mặt "ánh sáng" đòi hỏi nhiều nỗ lực hơn nhưng mang lại kết quả cao hơn. Mặt "tối" là nhanh chóng và dễ dàng và mang lại lợi ích lớn hơn ngay lập tức nhưng làm hỏng bạn xuống đường. Một khi bạn bắt đầu xuống con đường đen tối, mãi mãi nó sẽ thống trị vận mệnh của bạn.

Tôi gặp phải điều này mọi lúc, ở mọi công việc tôi từng làm, nó giống như một lời nguyền mà tôi không thể thoát ra. Văn hóa công ty luôn là con đường của mặt tối, và hack / sửa chữa nhanh chóng để đưa ra các tính năng mới, và những lời cầu xin và tái cấu trúc mã của tôi rơi vào tai người điếc, nếu điều đó không dẫn đến việc tôi chấm dứt " cố gắng thay đổi mọi thứ "(không có trò đùa nào tôi đã xảy ra trong một vài lần, bởi vì tôi muốn giới thiệu các mẫu thiết kế và tránh xa các bản hack nhanh).

Sự thật đáng buồn là thường thì cách ngu ngốc / đen tối là cách bạn phải bước đi, bạn chỉ cần đảm bảo bước đi nhẹ nhàng. Tôi đã chậm chạp và buồn bã nhận ra rằng lập trình viên hiểu đúng cách để viết các phần mềm, tức là sau RẮN, sử dụng các mẫu thiết kế, tuân SoC, vv được ít phổ biến hơn so với hacks tránh khỏi thất bại, những người sẽ viết một iftuyên bố để sửa chữa một lỗi, và khi có nhiều lỗi phát sinh, chỉ cần thêm vào câu lệnh đó thay vì nghĩ "Có lẽ cách nào tốt hơn để làm điều này" và tái cấu trúc mã để có thể mở rộng đúng cách.


3
iflà dễ dàng hơn nhiều để duy trì hơn IAbstractBugFixertừ một IAbstractBugFixerFactory. Khi, và, NẾU, bạn có thể thêm một giây if, sau đó là thời gian để cấu trúc lại. Các mẫu thiết kế và RẮN rất quan trọng trong giai đoạn kiến ​​trúc, nhưng không phải khi sản phẩm đã chạy và được viết theo một phong cách mà tất cả các thành viên trong nhóm đã đồng ý.
Coder

@Coder Cố gắng không cho rằng kiến ​​trúc không thể thay đổi bất cứ lúc nào. Nó có thể và làm được.
Ricky Clarkson

1
Wayne M, tôi có thể đồng cảm với các tình huống công việc của bạn. Ở lại với Lực. :)
Jennifer S

3

Nhận thức được những gì có thể xảy ra (tương lai) KHÔNG BAO GIỜ xấu. Suy nghĩ về những gì có thể là một cách tốt hơn để làm một cái gì đó là một phần của những gì làm cho bạn giỏi trong công việc của bạn. Phần khó hơn là xác định xem thời gian sử dụng: tỷ lệ hoàn trả có hợp lý hay không. Chúng ta đều đã thấy những tình huống mà mọi người thực hiện "dễ dàng nếu" để cầm máu ngay lập tức (và / hoặc la hét), và khi những điều đó cộng lại, bạn sẽ nhận được mã khó hiểu. Nhiều người trong chúng ta cũng đã trải qua sự trừu tượng hóa quá mức, đó là một bí ẩn một khi lập trình viên gốc bắt đầu, điều này cũng tạo ra mã khó hiểu.

Tôi sẽ xem xét tình huống của bạn và hỏi những câu hỏi sau:

  1. Mã này có phải là nhiệm vụ quan trọng không, và nó sẽ ổn định hơn đáng kể nếu tôi viết lại mã? Trong phẫu thuật nói, đây là tái cấu trúc cuộc sống, hoặc nó chỉ là tự chọn và mỹ phẩm?

  2. Tôi có đang xem xét tái cấu trúc mã mà chúng tôi sẽ thay thế trong 6 tháng không?

  3. Tôi có sẵn sàng dành nhiều thời gian để viết tư liệu thiết kế và lý do của tôi cho các nhà phát triển trong tương lai như tôi dành để thực hiện tái cấu trúc không?

  4. Về thiết kế thanh lịch của tôi để thêm các tính năng trong tương lai, đây có phải là mã mà người dùng yêu cầu thay đổi mỗi tuần hay đây là lần đầu tiên tôi chạm vào nó trong năm nay?

Có những lúc YAGNI và KISS giành chiến thắng trong ngày, nhưng có những ngày, một sự thay đổi cơ bản sẽ đưa bạn thoát khỏi vòng xoáy đi xuống đến sự điên rồ. Miễn là bạn thực tế trong đánh giá của bạn về không chỉ những gì bạn muốn, mà cả những gì người khác sẽ phải làm để duy trì công việc của bạn, bạn sẽ có thể xác định tốt hơn tình huống nào. Ồ, và đừng quên viết ra những gì bạn đã làm, và tại sao. Nó sẽ cứu những người theo dõi bạn, mà cả chính bạn khi bạn phải quay lại sau.


3

Trong phiên bản thứ hai của Stroustrups 'Ngôn ngữ lập trình C ++', (Tôi không có trang này) Tôi đã đọc

Đừng thêm mã tự phát tại chỗ.

và tôi đã làm tốt theo lời khuyên. Tất nhiên là có sự đánh đổi, và bạn phải tìm sự cân bằng, nhưng những đoạn ngắn có thể kiểm chứng tốt hơn một mớ mì spaghetti lớn.

Tôi thường trải nghiệm rằng trong khi phân biệt từ một trường hợp đến hai trường hợp, nếu bạn nghĩ về 2 trường hợp là n, bạn sẽ mở ra một cánh cửa cho nhiều khả năng mới, điều mà bạn có thể không nghĩ tới.

Nhưng sau đó bạn phải đặt câu hỏi YAGNI: Có đáng không? Nó sẽ thực sự hữu ích? Có kinh nghiệm có nghĩa là, bạn sẽ hiếm khi sai, và là người mới bắt đầu thường xuyên sai hơn.

Bạn nên đủ quan trọng để nhận ra một mẫu và phát hiện xem mã của bạn có khó bảo trì hay không, vì quá nhiều trừu tượng hoặc khó bảo trì, vì mọi thứ đều được giải quyết.

Giải pháp không phải là cái này hay cái kia, mà là nghĩ về nó. :)


2

"mã tốt chỉ có thể làm A còn tệ hơn mã xấu có thể làm A, B, C và D."

Điều này có thể có ý nghĩa trong việc phát triển sản phẩm; Nhưng hầu hết các chuyên gia CNTT làm việc trong 'dự án' thay vì phát triển sản phẩm.

Trong 'Dự án CNTT', nếu bạn lập trình một Thành phần tốt, nó sẽ hoạt động trơn tru trong suốt thời gian tồn tại của dự án - có thể không kéo dài quá 5 hoặc 10 năm sau đó kịch bản kinh doanh có thể đã lỗi thời và một dự án / ERP mới sản phẩm có thể đã thay thế nó. Trong vòng đời 5/10 năm này, trừ khi có lỗi trong mã của bạn, không ai sẽ nhận thấy sự tồn tại của nó và những suy nghĩ tốt nhất của bạn sẽ không được chú ý! (trừ khi bạn giỏi cá cược kèn của mình!)

Không nhiều người có cơ hội lập trình 'Windows Ctl + Alt + Del' và một số ít có cơ hội đó có thể không nhận ra tiềm năng tương lai của mã của họ!


1

Nhiều cuốn sách về phát triển tinh gọn và / hoặc nhanh nhẹn sẽ giúp củng cố phương pháp này: làm những gì cần thiết ngay bây giờ. Nếu bạn biết bạn đang xây dựng một khung, sau đó thêm vào các tóm tắt. Nếu không, đừng thêm phức tạp cho đến khi bạn cần nó. Tôi khuyên bạn nên phát triển phần mềm Lean , sẽ giới thiệu nhiều khái niệm khác có thể tạo ra sự khác biệt đáng kể về năng suất.


1

Thật buồn cười khi mọi người nói về cách làm đúng / cách làm sai. Đồng thời, nhiệm vụ lập trình vẫn còn rất khó khăn và không đưa ra giải pháp tốt nào cho việc viết các hệ thống phức tạp lớn.

Có thể một ngày nào đó chúng ta, các lập trình viên, cuối cùng sẽ tìm ra cách viết phần mềm phức tạp. Cho đến lúc đó tôi đề nghị bạn luôn bắt đầu với việc triển khai nguyên mẫu "ngu ngốc" trước, và sau đó dành thời gian vừa đủ cho việc tái cấu trúc để các trường đại học của bạn có thể theo mã của bạn.


1
Trong hầu hết các trường hợp, bạn sẽ không bao giờ có thời gian đặc biệt để tái cấu trúc - đó có lẽ là lý do chính cho tất cả những điều này "Chúng tôi không thể thực hiện điều này mà không thực hiện lại điều đó" ;-) Bạn có thể thực hiện đúng cách ngay từ đầu hoặc bạn làm điều đó sai cách mọi lúc.
Andrey Agibalov

@ loki2302: Hãy nhớ rằng viết mã mới luôn dễ dàng hơn. Bạn sẽ nhanh gấp đôi khi tạo mẫu mã ngu ngốc, sau đó năng suất của bạn sẽ giảm xuống 0 trong khoảng một nửa thời gian. Vì vậy, cuối cùng bạn vẫn sẽ nhanh như các lập trình viên cố gắng thiết kế đúng cách ..
AareP

1

Nhìn thấy những thiết kế quá sớm như vậy hoàn toàn không phù hợp với yêu cầu thực tế xuất hiện sau đó, tôi đã nghĩ ra một quy tắc cho tôi:

Đối với các yêu cầu giả thuyết chỉ viết mã giả thuyết.

Đó là: bạn nên suy nghĩ về những thay đổi có thể xảy ra sau này. Nhưng chỉ sử dụng những hiểu biết này để chọn một thiết kế cho mã có thể dễ dàng thay đổi và tái cấu trúc nếu những yêu cầu đó thực sự xuất hiện. Bạn thậm chí có thể viết một số mã trong đầu (mã giả định) mà bạn muốn viết trong trường hợp đó, nhưng không viết bất kỳ mã thực tế nào!


0

Tôi nghĩ rằng tư duy sẽ giúp bạn là luôn luôn phấn đấu cho các giải pháp cụ thể cho các vấn đề mã hóa thay vì các giải pháp trừu tượng. Tóm tắt chỉ nên được thêm khi chúng thực sự giúp đơn giản hóa cơ sở mã (ví dụ khi chúng cho phép bạn làm cho cơ sở mã nhỏ hơn).

Nhiều lập trình viên đã phát hiện ra rằng các tóm tắt xuất hiện gần như một mình, khi họ DRY mã của họ lên. Các mẫu thiết kế và thực tiễn tốt nhất giúp bạn tìm thấy cơ hội để làm việc đó, nhưng bản thân chúng không phải là mục tiêu đáng để theo đuổi.


0

Tôi nghĩ rằng kỹ thuật quá mức thường có vẻ từ sự không an toàn về việc viết mã. Tất cả các nguyên tắc và mô hình trừu tượng nên được coi là công cụ để giúp bạn. Điều thường xảy ra là chúng được coi là tiêu chuẩn, người ta phải tuân thủ.

Tôi tin rằng một lập trình viên luôn ở vị trí tốt hơn để quyết định làm thế nào để trừu tượng hơn một tiên đề.

Phần còn lại đã được KeithS nói


Tôi nghĩ một cách để có được sự tự bảo mật về việc viết mã là mã hóa bằng root trên hệ thống linux. Nếu bạn gõ willy-nilly, boom, bạn sẽ phải đánh giá lại VM. Dạy tất cả các loại thói quen tốt thực sự nhanh chóng. Hãy chắc chắn rằng hộp của bạn sống trong internet thực và đảm bảo bạn nhìn vào nhật ký. (ssh, http) Đó cũng là những niềm vui thực sự!
Christopher Mahan

Phiên bản của tôi là: Bỏ qua các nguyên tắc bạn không hiểu. Nếu bạn quyết định sử dụng chúng, đừng đối xử với họ nghiêm túc hơn bạn sẽ tập thể dục.
phá hoại

0

Hãy tự hỏi những lợi thế của một thiết kế tốt là gì:

  • Dễ hiểu
  • Duy trì dễ dàng hơn
  • Di động
  • Vẫn còn hữu ích trong một thời gian dài
  • Dễ dàng thêm các tính năng mới

Bây giờ, hãy tự hỏi nếu thêm tất cả các lớp trừu tượng đó thực sự thêm vào bất kỳ điểm nào được đề cập ở trên. Nếu không, bạn đang làm nó SAI .

Nếu bạn có thể thêm một tính năng mới bằng cách thêm 3 dòng mã như thế này:

if (condition()) {
  doSomething()
}

Sau đó, xin vui lòng, xin vui lòng làm như vậy. Điều này cho thấy thiết kế trước đây của bạn là tốt và dễ thích nghi. Chỉ khi các lớp của bạn bắt đầu phát triển vượt quá một mức mở rộng nhất định, hãy sử dụng tái cấu trúc để phân tách các hàm và có thể trích xuất các lớp mới.

Nguyên tắc nhỏ của tôi là các tính năng mới nên được triển khai tối giản nhất có thể, chỉ khi có thứ gì đó lớn để nắm bắt trước (giả sử, mất hơn 1 ngày hoặc nửa ngày để thực hiện), bạn có thể thêm một thiết kế toàn cầu thô. Từ đó, chỉ thêm các lớp trừu tượng khi kích thước của mã tăng lên. Sau đó bạn tái cấu trúc lại! Sau một thời gian, nó thậm chí sẽ trở nên tự nhiên với bạn khi bạn cần thiết kế một mảnh nhiều hơn một chút, hoặc đi cho con đường nhanh chóng. Một dấu hiệu khác cho thấy một số mã có thể sử dụng một số dọn dẹp là khi bạn sử dụng lại nó. Mỗi khi bạn thêm một tính năng mới hoặc gọi mã cũ ở một địa điểm mới, đó là thời điểm tốt để xem mã cũ và xem liệu bạn có thể cải thiện nó một chút trước khi bạn thêm lại nó không. Bằng cách này, mã nóng sẽ dần trở nên sạch sẽ hơn, trong khi các phần không quan tâm sẽ dần dần biến mất và không mất bất kỳ thời gian quý báu nào của bạn.

Nếu bạn làm việc như thế này, bạn sẽ không bao giờ thiết kế quá nhiều. Có thể cần một số kỷ luật để quay lại mã cũ khi bạn muốn thêm một cái gì đó mới hoặc để lại mã mới xấu hơn một chút sau đó bạn thích, nhưng bạn sẽ làm việc theo hướng hiệu quả thay vì thiết kế quá mứ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.