Những thực hành tốt nhất phổ biến của người Viking không phải lúc nào cũng tốt nhất, và tại sao? [đóng cửa]


100

"Thực hành tốt nhất" ở khắp mọi nơi trong ngành công nghiệp của chúng tôi. Một tìm kiếm của Google về "thực hành tốt nhất về mã hóa" cho ra gần 1,5 triệu kết quả. Ý tưởng dường như mang lại sự thoải mái cho nhiều người; Chỉ cần làm theo hướng dẫn, và mọi thứ sẽ trở nên tốt đẹp.

Khi tôi đọc về một thực tiễn tốt nhất - ví dụ, tôi mới đọc qua vài bài trong Clean Code gần đây - tôi cảm thấy lo lắng. Điều này có nghĩa là tôi nên luôn luôn sử dụng thực hành này? Có điều kiện kèm theo? Có những tình huống mà nó có thể không phải là một thực hành tốt? Làm thế nào tôi có thể biết chắc chắn cho đến khi tôi biết thêm về vấn đề này?

Một số thực tiễn được đề cập trong Clean Code không phù hợp với tôi, nhưng tôi thực sự không chắc đó có phải là vì chúng có khả năng xấu hay không, nếu đó chỉ là sự thiên vị cá nhân của tôi. Tôi biết rằng nhiều người nổi bật trong ngành công nghệ dường như nghĩ rằng không có thực tiễn tốt nhất , vì vậy ít nhất những nghi ngờ dai dẳng của tôi đặt tôi vào một công ty tốt.

Số lượng thực tiễn tốt nhất tôi đã đọc chỉ đơn giản là quá nhiều để liệt kê ở đây hoặc đặt câu hỏi riêng lẻ, vì vậy tôi muốn diễn đạt điều này như một câu hỏi chung:

Những thực hành mã hóa nào được gắn nhãn phổ biến là "thực tiễn tốt nhất" có thể không tối ưu hoặc thậm chí có hại trong một số trường hợp nhất định? Những hoàn cảnh đó là gì và tại sao họ làm cho việc thực hành trở nên nghèo nàn?

Tôi muốn nghe về các ví dụ và kinh nghiệm cụ thể.


8
Đó là những thực hành bạn không đồng ý với?, Chỉ tò mò.
Sergio Acosta

Bất cứ ai cũng có thể viết một cuốn sách và tôi không cần phải đồng ý với nó - nó đơn giản như vậy.
Công việc

Một điều tôi thích về cuốn sách "Code Complete" của Steve McConnell là ông sao lưu tất cả các mẹo của mình với bằng chứng và nghiên cứu khó khăn. Chỉ cần nói
JW01

5
@Walter: Điều này đã được mở trong nhiều tháng, nó chắc chắn mang tính xây dựng, tại sao lại đóng nó?
Orble

2
Nhìn thấy tên của tôi đang được đề cập ở đây, tôi cho rằng tôi nên nói: Tôi tin rằng các câu trả lời ở đây là có giá trị, nhưng câu hỏi có thể được đặt lại thành một cái gì đó chắc chắn giống như cuộc thăm dò mà không làm mất hiệu lực của bất kỳ câu trả lời nào. Tiêu đề ví dụ: "Những 'thực tiễn tốt nhất' phổ biến nào đôi khi có thể gây hại và khi nào / tại sao?"
Aaronaught

Câu trả lời:


125

Tôi nghĩ rằng bạn đã đánh vào đầu với tuyên bố này

Tôi ghét lấy mọi thứ theo mệnh giá và không nghĩ về chúng một cách nghiêm túc

Tôi bỏ qua gần như tất cả các Thực tiễn Tốt nhất khi nó không đi kèm với lời giải thích về lý do tại sao nó tồn tại

Raymond Chen đưa nó tốt nhất trong bài viết này khi ông nói

Lời khuyên tốt đi kèm với một lý do để bạn có thể biết khi nào nó trở thành lời khuyên tồi. Nếu bạn không hiểu tại sao nên làm gì đó, thì bạn đã rơi vào cái bẫy của lập trình sùng bái hàng hóa, và bạn sẽ tiếp tục làm điều đó ngay cả khi không còn cần thiết hoặc thậm chí trở nên khó hiểu.


4
Trích dẫn tuyệt vời.
David Thornley

Đoạn tiếp theo của trích dẫn Raymond Chen có lẽ là mô tả ký hiệu Hungary! Hầu hết các công ty tôi thấy sử dụng nó mà không có lý do thực sự tốt mà họ có thể giải thích.
Craig

3
Tuy nhiên, tôi hy vọng mọi người không coi đây là một cái cớ để không tìm hiểu lý do đằng sau các thực tiễn tốt nhất là gì. ;) Thật không may, tôi đã thấy các nhà phát triển với thái độ này.
Vetle

3
Cơ sở lý luận là tốt. Nghiên cứu là tốt hơn.
Jon Purdy

7
Hoàn toàn đúng, và tôi đã nói như vậy trước đây. Có lẽ tiêu chuẩn đầu tiên trong bất kỳ tài liệu "Tiêu chuẩn" nào cũng nên đọc, "Vì lợi ích của việc chia sẻ kiến ​​thức và cung cấp thông tin cần thiết để hủy bỏ các tiêu chuẩn sau này, tất cả các tiêu chuẩn sẽ bao gồm các lý do cho sự tồn tại của chúng."
Scott Whitlock

95

Cũng có thể ném cái này vào vòng:

Premature optimization is the root of all evil.

Không, không phải vậy.

Báo giá đầy đủ:

"Chúng ta nên quên đi những hiệu quả nhỏ, nói khoảng 97% thời gian: tối ưu hóa sớm là gốc rễ của mọi tội lỗi. Tuy nhiên, chúng ta không nên bỏ qua cơ hội của mình trong 3% quan trọng đó."

Điều đó có nghĩa là bạn tận dụng các cải tiến hiệu suất chiến lược cụ thể trong suốt quá trình thiết kế của mình. Nó có nghĩa là bạn sử dụng các cấu trúc dữ liệu và thuật toán phù hợp với mục tiêu hiệu suất. Nó có nghĩa là bạn nhận thức được các cân nhắc thiết kế ảnh hưởng đến hiệu suất. Nhưng điều đó cũng có nghĩa là bạn không tối ưu hóa một cách phù phiếm khi làm như vậy sẽ mang lại cho bạn những lợi ích nhỏ với chi phí bảo trì.

Các ứng dụng cần phải được kiến ​​trúc tốt, để cuối cùng chúng không bị rơi khi bạn áp dụng một chút tải cho chúng, và sau đó bạn sẽ viết lại chúng. Điều nguy hiểm với trích dẫn rút gọn là, tất cả quá thường xuyên, các nhà phát triển sử dụng nó như một cái cớ để không nghĩ về hiệu suất cho đến khi kết thúc, khi có thể quá muộn để làm bất cứ điều gì về nó. Tốt hơn hết là xây dựng hiệu suất tốt ngay từ đầu, miễn là bạn không tập trung vào những chi tiết vụn vặt.

Giả sử bạn đang xây dựng một ứng dụng thời gian thực trên một hệ thống nhúng. Bạn chọn Python làm ngôn ngữ lập trình, bởi vì "Tối ưu hóa sớm là gốc rễ của mọi tội lỗi". Bây giờ tôi không có gì chống lại Python, nhưng nó một ngôn ngữ được giải thích. Nếu khả năng xử lý bị hạn chế và một số lượng công việc nhất định cần được thực hiện trong thời gian thực hoặc gần thời gian thực và bạn chọn một ngôn ngữ đòi hỏi nhiều sức mạnh xử lý cho công việc hơn bạn có, bạn thực sự bị lừa, bởi vì bạn bây giờ phải bắt đầu lại với một ngôn ngữ có khả năng.


4
+1 cho kẻ mạnh Không, không phải vậy.
Stephen

21
Nhưng nếu bạn đã nhận ra rằng một tối ưu hóa cụ thể nằm trong 3% quan trọng đó, bạn có sớm tối ưu hóa nó không?
Giăng

7
@Robert: Vậy thì điểm bất đồng với tuyên bố rằng "Tối ưu hóa sớm là gốc rễ của mọi tội lỗi" là gì?
Giăng

8
Không bao giờ là sớm để tối ưu hóa các quyết định thiết kế và kỹ thuật cấp cao như lựa chọn ngôn ngữ. Tuy nhiên, thường thì chỉ sau khi bạn hoàn thành một thiết kế thì sự thiếu hiệu quả của nó mới trở thành vô nghĩa, đó là lý do tại sao Fred Brooks nói rằng hầu hết các đội viết một phiên bản ném đi dù họ có ý định hay không. Một lập luận khác cho nguyên mẫu.
Dominique McDonnell

8
@Robert, báo giá Knuth đã được tối ưu hóa sớm ...

94

Một trả về cho mỗi chức năng / phương thức.


7
Tôi sẽ đặt cái này Tôi yêu tôi một số tuyên bố trở lại sớm.
Carson Myers

4
Chắc chắn rồi! Mọi người tạo ra một số luồng chương trình khá thú vị để tránh một returntuyên bố sớm . Cấu trúc điều khiển lồng nhau sâu hoặc kiểm tra liên tục. Điều này thực sự có thể làm nở một phương pháp khi một if returnthực sự có thể đơn giản hóa vấn đề này.
snmcdonald

4
Nếu bạn cần nhiều lợi nhuận trong một chức năng (ngoài các vệ sĩ) thì chức năng của bạn có thể quá dài.
EricSchaefer

18
Không có điểm nào có từ khóa trả về trừ khi nó được dự định xuất hiện ở nhiều nơi. Trở về sớm, trở về thường xuyên. Nó sẽ chỉ phục vụ để đơn giản hóa mã của bạn hơn nữa. Nếu mọi người có thể hiểu làm thế nào các tuyên bố phá vỡ / tiếp tục hoạt động, tại sao họ đấu tranh với sự trở lại?
Evan Plaice

7
Tôi nghĩ rằng đây là một thực tiễn tốt nhất rất lỗi thời. Tôi không nghĩ đó là một thực hành tốt nhất hiện đại.
Skilldrick

87

Đừng phát minh lại bánh xe là một giáo điều được sử dụng rộng rãi. Ý tưởng của nó là nếu tồn tại một giải pháp phù hợp, hãy sử dụng nó thay vì tạo ra giải pháp của riêng bạn; ngoài nỗ lực tiết kiệm, giải pháp hiện tại có khả năng được triển khai tốt hơn (không có lỗi, hiệu quả, đã được kiểm tra) so với những gì bạn sẽ đưa ra ban đầu. Càng xa càng tốt.

Vấn đề là hiếm khi có giải pháp phù hợp 100%. Một giải pháp phù hợp 80% có thể tồn tại, và sử dụng nó có lẽ là tốt. Nhưng làm thế nào khoảng 60% phù hợp? 40%? Bạn ve con đương nay ở đâu vậy? Nếu bạn không vẽ đường, cuối cùng bạn có thể kết hợp một thư viện cồng kềnh vào dự án của mình vì bạn đang sử dụng 10% các tính năng của nó - chỉ vì bạn muốn tránh "phát minh lại bánh xe".

Nếu bạn phát minh lại bánh xe, bạn sẽ có được chính xác những gì bạn muốn. Bạn cũng sẽ học cách làm bánh xe. Học bằng cách không nên đánh giá thấp. Và cuối cùng, một bánh xe tùy chỉnh có thể tốt hơn so với bánh xe chung ngoài giá.


3
Tôi đã có điều này xảy ra theo cách khác xung quanh. Tôi đã xây dựng thành phần lưới ajax của riêng mình bởi vì vào thời điểm đó, không có cái nào làm được điều tôi muốn, nhưng sau đó đã thay thế nó bằng lưới Ext JS. Nó đã giúp tôi đưa ra giả định ngay từ đầu rằng lớp hiển thị sẽ được thay thế.
Joeri Sebrechts

20
Đã đồng ý. Nếu không ai từng phát minh lại bánh xe, thì tất cả chúng ta sẽ lái những chiếc xe của mình bằng lốp gỗ.
Học viên của Tiến sĩ Wily

6
Tôi luôn cảm thấy như ví dụ 10% của bạn khi tôi thêm Boost vào dự án C ++. Tôi luôn luôn cần ít hơn 10% trong số đó, nhưng tất nhiên các chức năng tôi cần nhập các mô-đun khác nhập các mô-đun khác ...
Roman Starkov

3
+1: chỉ trong tuần này, tôi đã phát minh lại bánh xe (ví dụ: thay thế plugin jquery cồng kềnh nhưng phổ biến mà chúng tôi sử dụng bằng thứ gì đó phù hợp với nhu cầu của chúng tôi theo mô-đun) và nó mang lại hiệu suất rất lớn. Ngoài ra, có những người có công việc theo nghĩa đen là phát minh lại bánh xe: lấy Michelin làm ví dụ, họ làm R & D để cải thiện lốp xe.
wildpeaks

2
@Dr. Wily, những bánh xe không được phát minh lại, chúng đã được tái cấu trúc!

78

"Đơn vị kiểm tra mọi thứ."

Tôi đã nghe nói rằng tất cả các mã nên có các bài kiểm tra đơn vị, một điểm tôi không đồng ý. Khi bạn có một thử nghiệm cho một phương thức, bất kỳ thay đổi nào đối với đầu ra hoặc cấu trúc của phương thức đó phải được thực hiện hai lần (một lần trong mã, một lần trong thử nghiệm).

Như vậy, theo tôi, các thử nghiệm đơn vị phải tỷ lệ thuận với sự ổn định cấu trúc của mã. Nếu tôi đang viết một hệ thống lớp từ dưới lên, lớp truy cập dữ liệu của tôi sẽ kiểm tra wazoo; Lớp logic kinh doanh của tôi sẽ được kiểm tra khá tốt, lớp trình bày của tôi sẽ có một số thử nghiệm và quan điểm của tôi sẽ có ít hoặc không có thử nghiệm.


7
Tôi nghi ngờ rằng "Đơn vị kiểm tra mọi thứ" đã trở thành một sáo ngữ, như trích dẫn "tối ưu hóa sớm". Tôi thường đồng ý với tỷ lệ của bạn và đã thấy nhiều ví dụ về các nhà phát triển trải qua nỗ lực hoành tráng để chế nhạo một đối tượng lớp ứng dụng, nỗ lực có thể được chi tiêu tốt hơn khi thực hiện kiểm tra chấp nhận.
Robert Harvey

36
Nếu thay đổi cấu trúc của phương thức gây ra thay đổi trong các thử nghiệm của bạn, bạn có thể đang thử nghiệm sai. Kiểm tra đơn vị không nên xác minh thực hiện, chỉ có kết quả.
Adam Lear

7
@Anna Lear: Tôi nghĩ rằng anh ấy đã nói về việc thay đổi thiết kế / cấu trúc (tái cấu trúc). Vì thiết kế không đủ chín chắn, nên khi bạn tìm ra cách tốt hơn để làm nó, bạn có thể phải sửa đổi rất nhiều thử nghiệm theo cách này. Tôi đồng ý rằng khi bạn là người thử nghiệm có kỹ năng hơn, bạn có thể dễ dàng nhận thấy thử nghiệm sẽ là ý tưởng tồi (vì lý do này và những người khác) nhưng nếu thiết kế không thực sự trưởng thành, bạn vẫn có thể có một số thử nghiệm trong đường.
n1ckp

13
Tôi nghĩ đây cũng là lý do tại sao ý tưởng "làm bài kiểm tra đầu tiên" không hoạt động. Để làm các bài kiểm tra đầu tiên, bạn phải có thiết kế đúng. Nhưng có thiết kế phù hợp đòi hỏi bạn phải thử mọi thứ và xem cách chúng hoạt động để bạn có thể cải thiện chúng. Vì vậy, bạn thực sự không thể thực hiện các thử nghiệm trước khi bạn có thiết kế và để thiết kế phù hợp yêu cầu bạn viết mã và xem nó hoạt động như thế nào. Trừ khi bạn có một số kiến ​​trúc sư thực sự uber, tôi không thực sự thấy ý tưởng đó sẽ hoạt động như thế nào.
n1ckp

13
@ n1ck TDD không thực sự là một bài tập thử nghiệm nhiều như nó là một bài tập thiết kế. Ý tưởng là bạn phát triển thiết kế của mình thông qua các thử nghiệm (vì nó nhanh chóng đưa ra API hợp lý cho công cụ của bạn) thay vì phù hợp với các thử nghiệm với thiết kế hiện có (có thể xấu / không đủ). Vì vậy, không, bạn không cần phải có quyền thiết kế để thực hiện các bài kiểm tra trước.
Adam Lear

57

Luôn lập trình để giao diện.

Đôi khi sẽ chỉ có một thực hiện. Nếu chúng ta trì hoãn quá trình trích xuất một giao diện cho đến khi chúng ta thấy cần nó, chúng ta thường sẽ thấy nó không cần thiết.


4
Đồng ý, bạn lập trình cho một giao diện khi bạn cần một giao diện (tức là API ổn định để làm việc).
Robert Harvey

45
Trong bài đọc của tôi, quy tắc này không phải là về các giao diện như các cấu trúc ngôn ngữ. Điều đó có nghĩa là bạn không nên đưa ra bất kỳ giả định nào về hoạt động bên trong của một lớp khi gọi các phương thức của nó và chỉ nên dựa vào các hợp đồng API.
Zsolt Török

2
Đây là một câu hỏi thú vị - Tôi chủ yếu là một nhà phát triển .NET vì vậy đối với tôi các giao diện của tôi trông giống như IBusinessManager hoặc IServiceContract. Đối với tôi điều này cực kỳ dễ điều hướng (và tôi thường giữ các giao diện của mình trong một không gian tên khác [hoặc thậm chí là một dự án khác]). Khi tôi đã sử dụng Java, tôi thực sự đã thấy điều này khó hiểu (nói chung là các triển khai giao diện mà tôi thấy có hậu tố .impl - và các giao diện không có phân định). Vì vậy, đây có thể là một vấn đề tiêu chuẩn mã? Tất nhiên các giao diện trong java làm cho mã trông lộn xộn - chúng trông giống hệt như các lớp bình thường ngay từ cái nhìn đầu tiên.
Watson

5
@Watson: một chi phí là mỗi lần tôi nhấn F3 ('nhảy tới khai báo') trong một lệnh gọi phương thức trong Eclipse, tôi sẽ chuyển sang giao diện, chứ không phải thực hiện. Sau đó tôi phải điều khiển-T, mũi tên xuống, quay trở lại để thực hiện. Nó cũng chặn một số phép tái cấu trúc tự động - ví dụ: bạn không thể định tuyến một phương thức qua một định nghĩa giao diện.
Tom Anderson

4
@Tom: Thưa ngài, tôi rất sẵn lòng tham gia vào cuộc chiến đó, Eclipse so với Intellij - tuy nhiên tôi có một quy tắc đạo đức nổi bật ngăn tôi khỏi phải đối đầu với một người có tật nguyền rõ ràng. BÙM. Tôi không nói rằng Eclipse là xấu, tôi đang nói rằng nếu các cường quốc của phe Trục đã sử dụng nó để xây dựng hoặc thiết kế các cỗ máy chiến tranh của họ, thì WWII giờ đây sẽ được gọi là "kerfuffle hai ngày". Nghiêm túc mà nói, tôi đã thấy rằng nó thiếu một số đánh bóng mà tôi có trong các IDE ngoài luồng (Intellij / VS + ReSharper). Tôi đã thấy mình chiến đấu với nó nhiều hơn một lần - đó là một quá nhiều.
Watson

46

Không sử dụng bất cứ thứ gì nguồn mở (hoặc không phải Microsoft cho các nhà phát triển .NET)

Nếu Microsoft không phát triển nó - chúng tôi sẽ không sử dụng nó ở đây. Muốn sử dụng ORM - EF, muốn sử dụng IOC - Unity, muốn đăng nhập - khối ứng dụng đăng nhập doanh nghiệp. Có rất nhiều thư viện tốt hơn tồn tại - nhưng tôi luôn bị kẹt khi đặt hàng từ menu đô la của thế giới phát triển. Tôi thề mỗi khi nghe Microsoft Thực hành tốt nhất tôi nghĩ rằng "Nguyên tắc dinh dưỡng của McDonald". Chắc chắn, bạn có thể sẽ sống nếu bạn theo dõi họ, nhưng bạn cũng sẽ bị suy dinh dưỡng và thừa cân.

  • Lưu ý rằng điều này có thể không phải là cách tốt nhất của bạn , nhưng nó là một cách phổ biến theo hầu hết mọi nơi tôi đã làm việc.

13
Nghe có vẻ kinh khủng ... = (Có lẽ tôi ở bên kia quá nhiều, tuy nhiên, tôi tránh M $ nhiều nhất có thể.
Lizzan

Đó không phải là cách đó. Một thư viện nên được chọn vì giá trị của nó, không chỉ xem xét ai đã tạo ra nó. Chẳng hạn, tôi yêu thích EF nhưng tôi đã có trải nghiệm tồi với Thư viện doanh nghiệp và tìm thấy các công cụ tốt hơn để xác thực và ghi nhật ký, chẳng hạn như FluentValidation, log4net và Elmah.
Matteo Mosca

4
Bạn sẽ không bị sa thải vì mua IBM ^ wMicrosoft
Christopher Mahan

17
Ngoài ra còn có phiên bản hình ảnh phản chiếu, tức là Không bao giờ sử dụng bất cứ thứ gì của Microsoft hoặc không bao giờ sử dụng bất cứ thứ gì bạn phải trả tiền.
Richard Gadsden

5
Tôi đủ may mắn để làm việc tại một tổ chức nơi đây không phải là một giáo điều được tổ chức rộng rãi, nhưng ở những nơi chúng tôi đã áp dụng các giải pháp thương mại, chắc chắn có rất nhiều nỗi đau. Vấn đề xảy ra khi một phần của giải pháp thương mại không hoạt động tốt. Khi nó là nguồn mở, bạn có thể xem nguồn (Tài liệu cuối cùng) và tìm hiểu những gì đang xảy ra. Với nguồn đóng, bạn phải trả tiền cho đặc quyền truy cập kiến ​​thức về hỗ trợ công nghệ, những người thậm chí còn biết ít hơn về sản phẩm mà bạn làm. Và đó là 'sửa chữa' duy nhất có sẵn.
Độc thân Khuyến khích

40

Hướng đối tượng

Có một giả định, chỉ vì mã là "hướng đối tượng", nó thật tuyệt vời. Vì vậy, mọi người tiếp tục ép chức năng vào các lớp và phương thức, chỉ để hướng đối tượng.


7
Tôi không thể tưởng tượng việc xây dựng một hệ thống phần mềm có kích thước đáng kể mà không tận dụng lợi thế của tổ chức mà Định hướng đối tượng cung cấp.
Robert Harvey

18
Robert. Unix không hướng đối tượng và chắc chắn nó đủ điều kiện là một hệ thống phần mềm có kích thước đáng kể. Nó dường như cũng khá phổ biến (nghĩ rằng Mac OSX, iPhone, điện thoại Android, v.v.)
Christopher Mahan

7
Ý tôi là tôi nghĩ chúng ta nên sử dụng phương pháp phù hợp nhất. Tôi đã thấy mọi người sử dụng các phương thức và các lớp mà nó cồng kềnh và không có nhiều ý nghĩa, chỉ vì "nó hướng đối tượng". Đó là sùng bái hàng hóa.
LennyProgrammer

8
Không có viên đạn bạc. Lập trình chức năng (Haskell) khá thành công mà không hướng đối tượng. Vào cuối ngày, bạn đã có nhiều công cụ và công việc của bạn là chọn loại tốt nhất cho nhiệm vụ trong tay.
Matthieu M.

9
Điều buồn cười là, bên cạnh việc sử dụng các lớp, đa hình và các lượt thích, hầu hết các mã hướng đối tượng trong thực tế là mã thủ tục.
Oliver Weiler

35

Tất cả các mã nên được bình luận.

Không, không nên. Đôi khi bạn có mã rõ ràng, ví dụ setters không nên được nhận xét, cho đến khi họ làm điều gì đó đặc biệt. Ngoài ra, tại sao tôi nên bình luận điều này:

/** hey you, if didn't get, it's logger. */
private static Logger logger = LoggerFactory.getLogger(MyClass.class);

13
Tất cả các mã nên được hiểu . Nhận xét là một công cụ chính trong đó, nhưng khác xa với chỉ có một.
Trevel

Vô tư, mã nên được hiểu. Nhưng không có lý do duy nhất để viết một bình luận mà sẽ không thêm bất cứ điều gì vào, ví dụ, tên phương thức. Nếu bạn viết /** sets rank. */ void setRank(int rank) { this.rank = rank; }tôi giả sử nhận xét là một ngu ngốc. Tại sao nó được viết?
Vladimir Ivanov

2
Tạo tài liệu. Đó là /** */định dạng dành cho thay vì /* */nhận xét định dạng. Hoặc đối với .NET, đó sẽ là///
Berin Loritsch

10
Sử dụng }//end if, }//end for, }//end whilelà những ví dụ tốt nhất của lãng phí cho ý kiến mà tôi từng gặp. Tôi đã thấy điều này nhiều lần khi niềng răng mở không quá 2 dòng ở trên. IMHO nếu bạn cần những bình luận này thì mã của bạn cần bao thanh toán lại ... hoặc bạn cần tăng 20 đô la và mua một trình soạn thảo IDE / Text làm nổi bật các dấu ngoặc phù hợp.
scunliffe

7
Mã nói "làm thế nào". Bình luận cần phải nói "tại sao".

32

Phương pháp, đặc biệt là scrum. Tôi không thể giữ khuôn mặt thẳng thắn khi nghe người lớn sử dụng cụm từ "Scrum Master". Tôi cảm thấy mệt mỏi khi nghe các nhà phát triển phản đối rằng một số khía cạnh của Phương pháp X không hoạt động cho công ty của họ, chỉ được nói bởi Đạo sư và vì vậy lý do nó không hoạt động là trên thực tế, họ không phải là những học viên thực thụ của Phương pháp X. "Scrum khó hơn, bạn phải, người học Padawan của tôi!"

Có rất nhiều sự khôn ngoan trong các phương pháp nhanh nhẹn --- rất nhiều trong số đó --- nhưng chúng thường bị vùi lấp trong quá nhiều phân đến nỗi tôi không thể chống lại phản xạ bịt miệng của mình. Lấy bit này từ trang scrum của Wikipedia :

Một số vai trò được xác định trong Scrum. Tất cả các vai trò thuộc hai nhóm khác nhau, lợn và gà, dựa trên bản chất của sự tham gia của chúng vào quá trình phát triển.

Có thật không? Lợn và gà, bạn nói gì? Lôi cuốn, hấp dẫn, quyến rũ! Không thể chờ đợi để đưa cái này cho sếp của tôi ...


Hấp dẫn. Tôi đồng ý với một mức độ nào đó. Với phần cuối cùng đó: hãy gọi cho họ những gì bạn muốn, họ là những người thường xuyên, đó là tất cả.
Steven Evers

12
+1 ... bạn nói đúng, thật khó để nghiêm túc. <giọng nói lớn đang bùng nổ> * TÔI LÀ SCRUMMASTER * </ voice>
GrandmasterB

2
Và các dụ ngôn. Nó làm tôi nhớ đến những bài giảng của nhà thờ, hoặc những giai thoại mà các bậc thầy tự lực (và diễn viên hài) nổi tiếng vì: "Hãy lấy bạn Steve của tôi. Steve đã liên tục cãi nhau với vợ Sheryl. Hai người sẽ đi đến đó hàng giờ, để thời điểm mà cuộc hôn nhân của họ gặp nguy hiểm thực sự. Rồi, một ngày nọ ... "Những loại sợi mô phạm này không làm phiền tôi trong các lĩnh vực khác, nhưng tôi ghét phải thấy chúng sinh sôi nảy nở trong khoa học kỹ thuật.
evadeflow

2
Còn các Scrum Ninjas thì sao?
Berin Loritsch

1
Tôi không đồng ý với so sánh "Lợn và Gà" ... nó bay thẳng vào mặt của Tuyên ngôn Agile. Cụ thể là "Sự hợp tác của khách hàng trong đàm phán hợp đồng". Khách hàng được trao quyền (nếu không phải là moreso) trong sự thành công của dự án với tư cách là nhóm dự án. Gọi một số vai lợn và các vai trò khác gà tạo ra một tâm lý "chúng ta so với chúng" rằng IMHO là rào cản lớn nhất cho các dự án thành công.
Michael Brown

25

Ánh xạ quan hệ đối tượng ... http://en.wikipedia.org/wiki/Object-relational_mapping

Tôi không muốn bị trừu tượng hóa khỏi dữ liệu của mình, tôi cũng không muốn mất sự kiểm soát và tối ưu hóa chính xác đó. Trải nghiệm của tôi với các hệ thống này cực kỳ kém ... Các truy vấn được tạo bởi các lớp trừu tượng này thậm chí còn tồi tệ hơn những gì tôi đã thấy từ việc tắt.


19
Tối ưu hóa sớm là gốc rễ của mọi tội lỗi. Mã chậm là, trong thực tế, chỉ hiếm khi là một vấn đề khi so sánh với mã không thể nhầm lẫn. Sử dụng ORM, sau đó cắt bỏ phần trừu tượng chỉ khi bạn cần.
Fishtoaster

28
ORM là một công cụ 80-20. Họ dự định xử lý 80% CRUD trở nên mệt mỏi để viết tất cả mã hệ thống ống nước vô tận đó sau một lúc. 20% khác có thể được thực hiện theo những cách "thông thường" hơn như sử dụng các thủ tục được lưu trữ và viết các truy vấn SQL thông thường.
Robert Harvey

18
@Fishtoaster: Ý bạn là, "Chúng ta nên quên đi những hiệu quả nhỏ, nói khoảng 97% thời gian: tối ưu hóa sớm là gốc rễ của mọi tội lỗi. Tuy nhiên, chúng ta không nên bỏ qua cơ hội của mình trong 3% quan trọng đó."?
Robert Harvey

5
@Robert Harcey: Có một lý do tôi không sử dụng trích dẫn trực tiếp. Tôi nghĩ rằng hầu hết các lập trình viên tập trung vào cách hiệu quả quá nhiều - đó là một vấn đề mà vài người trong số họ thực sự cần phải giải quyết. Phải thừa nhận rằng, có một số miền nhất định trong đó các miền quan trọng hơn các miền khác, nhưng khả năng duy trì và mở rộng là vấn đề ở mọi nơi. Một câu trích dẫn khác: "Làm cho nó hoạt động, làm cho nó có thể bảo trì, làm cho nó dễ đọc, làm cho nó có thể mở rộng, làm cho nó có thể kiểm tra được, và sau đó , nếu bạn có thời gian và hóa ra bạn cần nó, hãy làm cho nó nhanh chóng."
Fishtoaster

12
@Craig: Làm thế nào mà bạn không nhận ra sự trớ trêu trong tuyên bố của mình? Cần một năm để tìm hiểu làm thế nào để có được hiệu suất tốt từ ORM là một lập luận tuyệt vời chống lại ORM , cũng như cần phải "kiểm soát" SQL được tạo ra và thực hiện các thủ tục được lưu trữ. Nếu bạn có kiến ​​thức cho điều đó, bạn có kiến ​​thức để bỏ qua ORM hoàn toàn.
Nicholas Knight

22

Viết tên hàm như thể chúng là câu tiếng Anh:

Draw_Foo()
Write_Foo()
Create_Foo()

v.v ... Điều này có thể trông tuyệt vời, nhưng thật đau khổ khi bạn học API. Làm thế nào dễ dàng hơn để tìm kiếm một chỉ mục cho "Mọi thứ bắt đầu với Foo"?

Foo_Draw()
Foo_Write()
Foo_Create()

Vân vân.


2
Có lẽ dễ như gõ Foo trong danh sách chức năng của TM.
Josh K

68
Âm thanh như bạn thực sự muốn nó là Foo.Draw(), Foo.Write()Foo.Create(), để bạn có thể làm Foo.methods.sorthoặcFoo.methods.grep([what I seek]).sort
Inaimathi

7
Bắt đầu với 'Nhận' là một ví dụ khác.
JeffO

1
Tôi đến từ thế giới object-c, và rất nhớ tên phương thức dài dòng và ký hiệu infix khi tôi làm java (cuộc sống khác của tôi). Kể từ khi hoàn thành mã bắt đầu làm việc, tôi cũng không thấy vấn đề gõ thêm.

2
@Scott Whitlock: Không phải lỗi thời đối với một số nhà phát triển .NET, iirc, VS 2008 đã không làm điều đó. Mặc dù năm 2010, và nó thật tuyệt vời.
Steven Evers

22

MVC - tôi thường thấy rằng việc xử lý nhiều vấn đề thiết kế web trong cách tiếp cận MVC là về việc làm cho một khung (đường ray, v.v.) hài lòng hơn là về sự đơn giản hoặc cấu trúc. MVC là một yêu thích của "các phi hành gia kiến ​​trúc", người dường như đánh giá cao giàn giáo quá mức đơn giản. ymmv.

OO dựa trên lớp - theo tôi khuyến khích các cấu trúc phức tạp của trạng thái đột biến. các trường hợp hấp dẫn duy nhất tôi đã tìm thấy cho OO dựa trên lớp trong những năm qua là các ví dụ "hình dạng-> hình chữ nhật-> hình vuông" tạo thành chương 1 của bất kỳ cuốn sách OO nào


4
Tôi đã thực hiện phát triển web trong ASP.NET và ASP.NET MVC và, mặc dù MVC có vẻ khó hiểu, nhưng tôi thích nó hơn ASP.NET, vì nhiều lý do: đơn giản, dễ bảo trì và kiểm soát cực kỳ tốt đối với việc đánh dấu. Mọi thứ đều có vị trí của nó và, trong khi tất cả có vẻ hơi lặp lại, đó là một niềm vui để duy trì. Nó hoàn toàn có thể tùy chỉnh, vì vậy nếu bạn không thích một hành vi vượt trội, bạn có thể thay đổi nó.
Robert Harvey

1
Theo như OO, có những cách tốt và xấu để làm điều đó. Kế thừa được đánh giá cao và được sử dụng ít hơn trong thế giới thực so với hầu hết các cuốn sách mà bạn có thể tin tưởng; hiện đang có xu hướng hướng tới một phong cách phát triển bất biến hơn, nhiều chức năng hơn, ngay cả trong thế giới OO.
Robert Harvey

1
+1 để đề cập đến MVC. Trong khi khái niệm MVC (phân tách logic lớp dữ liệu, logic trình bày và logic nền là một ý tưởng tốt) thì việc phân tách chúng thành một hệ thống phân cấp thư mục phức tạp với một mớ hỗn hợp các tệp chứa đoạn mã là ngu ngốc. Tôi đổ lỗi cho toàn bộ hiện tượng này về sự thiếu hỗ trợ không gian tên của PHP và các nhà phát triển newbie tôn vinh các kỹ thuật đã tồn tại hàng thập kỷ là 'điều mới nhất'. Thật đơn giản, tạo một không gian tên cho các bộ truy cập cơ sở dữ liệu, GUI và logic nền (và các không gian tên phụ nếu cần).
Evan Plaice

3
Đối với OO, bạn sẽ không thực sự thấy lợi ích của nó cho đến khi dự án của bạn phát triển đến một quy mô mà việc quản lý sự phức tạp trở nên quan trọng. Thực hiện theo nguyên tắc trách nhiệm duy nhất bất cứ khi nào có thể và nếu mã của bạn có thể truy cập được hiển thị công khai (ví dụ: một)) ẩn việc triển khai nội bộ các lớp / phương thức / thuộc tính bất cứ nơi nào có thể để làm cho mã an toàn hơn và đơn giản hóa API.
Evan Plaice

1
Cá nhân tôi thấy ví dụ hình dạng-> hình chữ nhật-> hình vuông là một trong những đối số tao nhã nhất chống lại oop. ví dụ, Square(10).Draw()nó là đủ để Rectangle(10, 10).Draw(). vì vậy tôi đoán điều đó có nghĩa là hình vuông là một lớp con của hình chữ nhật. Nhưng mySquare.setWidthHeight(5,10)là vô nghĩa (IE, nó không thành công theo nguyên tắc thay thế Liskov), một hình vuông không thể có chiều cao và chiều rộng khác nhau, mặc dù hình chữ nhật có thể, do đó ngụ ý rằng hình chữ nhật là một lớp con của hình vuông. Điều này được biết đến trong các bối cảnh khác là "Vấn đề hình tròn, hình elip"
SingleNegationElimination

22

YAGNI

( Bạn sẽ không cần nó )

Cách tiếp cận này đã khiến tôi mất hàng giờ liền khi tôi phải triển khai các tính năng trên một cơ sở mã hiện có, trong đó việc lập kế hoạch cẩn thận sẽ bao gồm các tính năng này trước đó.

Ý tưởng của tôi thường bị từ chối vì YAGNI, và hầu hết những lần ai đó phải trả tiền cho quyết định đó sau đó.

(Tất nhiên người ta có thể lập luận rằng một cơ sở mã được thiết kế tốt cũng sẽ cho phép các tính năng được thêm vào sau này, nhưng thực tế thì khác)


15
Tôi đồng ý với YAGNI, nhưng tôi thấy những gì bạn đang làm. Quan điểm của YAGNI là đối phó với những người muốn lên kế hoạch cho mọi thứ từ trước đến từng chi tiết nhỏ nhất. Chín trong số mười lần, nó được sử dụng như một cái cớ để theo mã kỹ sư hoặc hoàn toàn bỏ qua kế hoạch.
Jason Baker

12
P.Floyd, @Jason Baker: +1 Hoàn toàn đúng. Câu nói cũ được áp dụng ở đây "vài tháng trong phòng thí nghiệm có thể tiết kiệm hàng giờ trong thư viện"
Steven Evers

Một đặc tả thường sẽ (và hầu hết nên) để lại phần lớn ý nghĩa và một số giao diện mở. mọi thứ không trực tiếp trong thông số kỹ thuật, nhưng được yêu cầu để thực hiện thông số kỹ thuật, cho dù quyết định thực hiện, giao diện người dùng có thể xem hay bất cứ điều gì khác, cũng là một yêu cầu gián tiếp của thông số kỹ thuật. Nếu một tính năng không có trong thông số kỹ thuật và không được ngụ ý bởi thông số kỹ thuật, thì bạn không cần nó. Làm thế nào điều này có thể gây nhầm lẫn?
Độc thân Khuyến khích

1
@TokenMacGuy khía cạnh quan trọng là ngụ ý của phần spec . Đó là nơi ý kiến ​​khác nhau rất nhiều.
Sean Patrick Floyd

20

Đối với SQL

  1. Không sử dụng kích hoạt
  2. Luôn ẩn bảng phía sau lượt xem

Theo thứ tự:

  1. Chúng là một tính năng có vị trí của nó. Bạn có nhiều đường dẫn cập nhật tới một bảng hoặc yêu cầu kiểm toán 100%?

  2. Chỉ là vì sao? Tôi sẽ làm nếu tôi tái cấu trúc để duy trì hợp đồng, nhưng không phải khi tôi đọc rằng dân gian thay đổi quan điểm để phù hợp với bất kỳ thay đổi bảng nào

Biên tập:

Số 3: Tránh * với EXISTS. Hãy thử 1/0. Nó hoạt động. Danh sách cột không được đánh giá theo tiêu chuẩn SQL. Trang 191


3
# 2 là một thực hành tốt nhất?
Hogan


1
@Hogan: Một khung nhìn chỉ đơn giản phản chiếu bảng cơ sở không thêm bảo mật khi sử dụng bảng cơ sở trực tiếp. Nếu bạn tham gia vào bảng bảo mật hoặc che dấu một số cột thì đủ công bằng. Nhưng CHỌN mỗi cột từ bảng hoặc dạng xem: không có sự khác biệt. Cá nhân, tôi vẫn sử dụng procs lưu trữ.
gbn

3
@Hogan: Tôi biết điều gì đó về SQL Server :-) stackoverflow.com/users/27535/gbn Những gì tôi có nghĩa là GRANT SELECT trên bảng không khác nhau để cấp lựa chọn về XEM nếu xem là SELECT * FROM TABLE
gbn

1
@gbn: Tôi đồng ý. Không có sự khác biệt ở đó. Tôi nghĩ rằng chúng ta có thể nói điều tương tự. Tôi đoán nhận xét ban đầu của tôi ("# 2 là cách thực hành tốt nhất?") Dựa trên kinh nghiệm cá nhân của tôi rằng các lượt xem (như trình kích hoạt) thường bị sử dụng sai hơn là sử dụng đúng. Do đó, một thực hành tốt nhất như vậy sẽ chỉ dẫn đến lạm dụng chứ không phải tăng cường. Nếu nó được coi là một thực hành tốt nhất, bạn đúng 100%, đó là một thực hành xấu.
Hogan

20

Mẫu thiết kế chủ yếu. Chúng được sử dụng quá mức và sử dụng.


13
+1 Tôi vẫn không thấy Mẫu thiết kế là giải pháp đẹp hay thanh lịch. Họ là giải pháp cho sự thiếu hụt ngôn ngữ, không có gì hơn.
Oliver Weiler

2
Chỉ xem đó là một nỗ lực của việc loại bỏ mùi ngôn ngữ bằng chính ngôn ngữ này.
Filip Dupanović

15

Nguyên tắc trách nhiệm duy nhất

("mỗi lớp chỉ nên có một trách nhiệm duy nhất; nói cách khác, mỗi lớp nên có một, và chỉ một, lý do để thay đổi")

Tôi không đồng ý. Tôi nghĩ rằng một phương thức chỉ nên có một lý do để thay đổi và tất cả các phương thức trong một lớp nên có mối quan hệ logic với nhau , nhưng chính lớp đó thực sự có thể làm một số điều (liên quan).

Theo kinh nghiệm của tôi, nguyên tắc này quá thường xuyên được áp dụng quá nhiệt tình và bạn kết thúc với nhiều lớp một phương thức nhỏ. Cả hai cửa hàng nhanh nhẹn mà tôi làm việc đã làm điều này.

Hãy tưởng tượng nếu những người tạo API .Net có loại tâm lý này: thay vì List.Sort (), List.Reverse (), List.Find (), v.v., chúng tôi sẽ có các lớp ListSorter, ListReverser và ListSearcher!

Thay vì tranh luận nữa với SRP (về lý thuyết không phải là khủng khiếp) , tôi sẽ chia sẻ một vài kinh nghiệm lâu đời của tôi:


Tại một nơi tôi làm việc, tôi đã viết một bộ giải lưu lượng tối đa rất đơn giản bao gồm năm lớp: một nút, một đồ thị, một người tạo biểu đồ, một trình giải đồ thị và một lớp để sử dụng trình tạo / giải đồ thị để giải quyết một vấn đề thực tế. Không có gì đặc biệt phức tạp hoặc dài (bộ giải cho đến nay là dài nhất với ~ 150 dòng). Tuy nhiên, quyết định rằng các lớp có quá nhiều "trách nhiệm", vì vậy các đồng nghiệp của tôi đã thiết lập về việc tái cấu trúc mã. Khi chúng được thực hiện, 5 lớp của tôi đã được mở rộng thành 25 lớp, với tổng số dòng mã nhiều hơn gấp ba lần so với ban đầu. Luồng mã không còn rõ ràng nữa, cũng không phải là mục đích của các bài kiểm tra đơn vị mới; Bây giờ tôi đã có một thời gian khó khăn để tìm ra những gì mã của riêng tôi đã làm.


Ở cùng một nơi, hầu hết mọi lớp chỉ có một phương thức duy nhất ("trách nhiệm" duy nhất của nó). Theo dòng chảy trong chương trình là gần như không thể, và hầu hết các bài kiểm tra đơn vị bao gồm kiểm tra rằng lớp này được gọi là mã từ một lớp khác , cả hai mục đích của chúng đều là một bí ẩn đối với tôi. Có hàng trăm lớp học chỉ có hàng chục (IMO) chỉ có hàng chục. Mỗi lớp chỉ làm một "điều" , nhưng ngay cả với các quy ước đặt tên như "AdminUserCreationAtteemorFactory" , rất khó để nói mối quan hệ giữa các lớp.


Ở một nơi khác (cũng có tâm lý chỉ nên có một lớp ), chúng tôi đã cố gắng tối ưu hóa một phương thức chiếm 95% thời gian trong một hoạt động nhất định. Sau khi (khá ngu ngốc) tối ưu hóa nó một chút, tôi chuyển sự chú ý của mình về lý do tại sao nó được gọi là một tỷ lần. Nó đã được gọi trong một vòng lặp trong một lớp ... có phương thức được gọi trong một vòng lặp trong một lớp khác .. cũng được gọi trong một vòng lặp ..

Tất cả đã nói, có năm cấp độ vòng lặp trải rộng trên 13 lớp (nghiêm túc). Điều mà bất kỳ một lớp nào đang thực sự làm là không thể xác định chỉ bằng cách nhìn vào nó - bạn phải phác thảo một biểu đồ tinh thần về phương thức mà nó gọi, và phương thức mà các phương thức đó gọi, v.v. Nếu tất cả đã được gộp thành một phương thức, thì nó sẽ chỉ dài khoảng 70 dòng với phương pháp vấn đề của chúng ta được lồng trong năm cấp độ vòng lặp rõ ràng ngay lập tức.

Yêu cầu của tôi để cấu trúc lại 13 lớp đó thành một lớp đã bị từ chối.


6
Âm thanh như ai đó bị "Sốt mẫu" hoặc trong trường hợp này là "Nguyên tắc sốt" trong công việc đó. Lớp danh sách không vi phạm SRP. Tất cả các chức năng của nó phục vụ một mục đích, thao túng một bộ sưu tập các đối tượng. Chỉ có một chức năng trong một lớp nghe có vẻ quá mức đối với tôi. Nguyên tắc đằng sau SRP là một đơn vị mã (có thể là phương thức, lớp hoặc thư viện) phải có một trách nhiệm duy nhất có thể được nêu rõ.
Michael Brown

3
Tôi đã bắt đầu thấy sự điên rồ này từ những người thấy rằng không thể viết mã chức năng thuần túy. Giáo dục quá nhiều rằng mọi vấn đề trên thế giới đều có thể được giải quyết từ một cuốn sách về các mẫu. Không đủ suy nghĩ về chủ nghĩa thực dụng. Giống như bạn, tôi đã thấy một số mã OO dựa trên lớp rất kinh khủng đến nỗi việc tuân theo nó là hoàn toàn không thể. Và nó rất lớn và bồng bềnh.
quick_now

3
Nhận xét thứ 2 tại đây. Rất nhiều "nguyên tắc" được áp dụng quá mức. Có nhiều điều là những ý tưởng tốt, trong đó thực hiện ngược lại đôi khi là thích hợp. Lập trình viên tốt biết khi phá vỡ các quy tắc. Bởi vì các quy tắc không phải là "quy tắc", chúng là những tuyên bố về "thực hành tốt hầu hết thời gian trừ khi đó là một ý tưởng thực sự ngu ngốc".
quick_now

"Hãy tưởng tượng nếu những người tạo API .Net có loại tâm lý này: thay vì List.Sort (), List.Reverse (), List.Find (), v.v., chúng tôi sẽ có các lớp ListSorter, ListReverser và ListSearcher ! ". Đây chính xác là những gì được thực hiện trong C ++, và nó thật tuyệt vời . Các thuật toán được tách ra khỏi các cấu trúc dữ liệu, vì vậy nếu tôi viết vùng chứa của riêng mình, tất cả các thuật toán hoạt động với thư viện chuẩn chỉ hoạt động với vùng chứa mới của tôi. Nó phải là khủng khiếp trong đất .Net, viết một chức năng sắp xếp mới cho mỗi container mới mà bạn muốn sắp xếp.
Mankude

14

Bây giờ bạn đã đề cập đến Clean Code, trong khi nó chứa một số ý tưởng hay, tôi nghĩ rằng nỗi ám ảnh của nó là tái cấu trúc tất cả các phương thức thành submethod và những cái đó thành sububmethods v.v ... đã đi quá xa. Thay vì một vài phương thức mười dòng, bạn nên thích hai mươi (được cho là cũng được đặt tên). Rõ ràng có ai đó nghĩ rằng nó sạch, nhưng với tôi nó dường như tồi tệ hơn phiên bản gốc.

Ngoài ra, thay thế những điều cơ bản đơn giản như

0 == memberArray.length

trong một lớp với một cuộc gọi đến phương thức riêng của lớp như

isEmpty()

là một "cải tiến" nghi vấn IMHO. Bổ sung: Sự khác biệt là kiểm tra đầu tiên thực hiện chính xác những gì nó nói: kiểm tra xem độ dài của mảng có bằng 0. Ok, cũng isEmpty()có thể kiểm tra độ dài của mảng. Nhưng nó cũng có thể được thực hiện như thế này:

return null != memberArray ? 0 == memberArray.length : true;

Đó là, nó bao gồm một kiểm tra null ngầm! Đây có thể là hành vi tốt đối với một phương thức công khai - nếu mảng là null, thì một cái gì đó chắc chắn trống rỗng - nhưng khi chúng ta nói về nội bộ lớp, điều này không tốt lắm. Mặc dù đóng gói ra bên ngoài là điều bắt buộc, các học viên trong lớp phải biết chính xác những gì đang diễn ra trong lớp. Bạn không thể gói gọn lớp từ chính nó . Rõ ràng là tốt hơn so với ngầm.


Điều này không có nghĩa là phá vỡ các phương pháp dài hoặc so sánh logic liên quan là không tốt; tất nhiên là vậy, nhưng ở mức độ nào để làm điều đó - nơi có điểm ngọt ngào - rõ ràng là một câu hỏi về hương vị. Việc chia nhỏ một phương pháp dài dẫn đến nhiều phương thức hơn và điều đó không miễn phí. Bạn phải nhảy xung quanh mã nguồn để xem điều gì đang thực sự xảy ra, khi bạn có thể thấy nó trong nháy mắt nếu tất cả những thứ đó nằm trong một phương thức duy nhất.

Tôi thậm chí còn đi xa hơn khi nói rằng trong một số trường hợp, phương pháp 1 dòng quá ngắn để xứng đáng là phương pháp.


6
Tôi hiếm khi xem đây là một vấn đề. Chủ yếu là vì tôi thường thấy quá nhiều trong một phương pháp duy nhất, không quá ít. Tuy nhiên, theo một số nghiên cứu độ phức tạp rất thấp trong các phương pháp cũng có tỷ lệ lỗi cao hơn một chút so với độ phức tạp thấp vừa phải. enerjy.com/blog/?p=198
MIA

Vâng, đây chắc chắn chỉ là một vấn đề trong Clean Code. Trong các phương pháp thực tế có xu hướng quá dài, như bạn đã nói. Nhưng thật thú vị khi nhìn thấy đường cong đó! Thật vậy, mọi thứ nên được làm đơn giản nhất có thể, nhưng không đơn giản hơn.
Joonas Pulakka

1
Tôi thấy ví dụ thứ hai của bạn dễ đọc hơn và hình thức đó (hoặc một cái gì đó tương tự, như thuộc tính Độ dài trên chính lớp) là điều bắt buộc nếu bạn công khai nó.
Robert Harvey

@Robert Harvey: Ví dụ thứ hai là một phương thức công khai tốt, nhưng việc gọi nó từ bên trong lớp là điều đáng nghi ngờ, bởi vì bạn không biết chính xác nó làm gì trước khi bạn nhìn cách nó được triển khai. Nó có thể kiểm tra null, ví dụ. Xem bổ sung của tôi ở trên.
Joonas Pulakka

@Joonas: Đủ công bằng.
Robert Harvey

13

"Hãy tự do với ý kiến"

Nhận xét chắc chắn là một điều tốt, nhưng quá nhiều cũng tệ như vậy nếu không tệ hơn là không đủ. Tại sao? Vâng, mọi người có xu hướng điều chỉnh các bình luận nếu họ thấy quá nhiều những thứ không cần thiết. Tôi không nói rằng bạn có thể có mã tài liệu hoàn toàn tự động, nhưng tốt hơn là mã cần bình luận để giải thích.


1
mã tài liệu tự chắc chắn là tốt đẹp. Mặc dù, tôi thích có các bình luận bên cạnh một cái gì đó như các phép tính đơn giản (để diễn tả giá trị của kiểu trả về hoặc giá trị trả về là gì). Tuy nhiên, nếu bình luận của bạn cần nhiều từ hơn mã, có lẽ đã đến lúc viết lại mã.
sova

6
Tôi phải đồng ý với cách mà sova đặt cái này. Mã sạch là thích hợp hơn để bình luận.
riwalk

4
Bạn vẫn cần "tại sao" trong đó!

Tôi muốn có ý kiến ​​giải thích lý do tại sao. Điều đó có nghĩa là tôi phải NGHINK ít hơn trong kỹ thuật đảo ngược ý định mã khi tôi đến để xem xét nó.
quick_now

12

GoTo được coi là có hại

Nếu bạn đang triển khai một máy trạng thái, một câu lệnh GOTO có thể có ý nghĩa hơn (mã dễ đọc và mã hiệu quả) hơn là cách tiếp cận "lập trình có cấu trúc". Nó thực sự lo lắng cho một số đồng nghiệp khi đoạn mã đầu tiên tôi viết trong một công việc mới không chỉ bao gồm một mà là một vài câu lệnh goto. May mắn thay, họ đủ thông minh để nhận ra rằng đó thực sự là giải pháp tốt nhất trong trường hợp cụ thể này.

Bất kỳ "thực hành tốt nhất" nào không cho phép các ngoại lệ hợp lý và được ghi lại theo quy tắc của nó chỉ là đáng sợ.


16
Tôi đang thực hiện chương trình chín năm mà không có một tuyên bố goto nào (bao gồm một số máy trạng thái, như bạn đã đề cập). Mở rộng tâm trí của bạn để những ý tưởng mới.
riwalk

3
@Mathieu M. - đã đồng ý - trộn GOTO với các câu lệnh điều khiển có cấu trúc là không hợp lý. (Đây hoàn toàn là C và nó không phải là vấn đề.
MZB

1
@ Stargazer2 - với một FSM đơn giản, nó phụ thuộc vào việc đặt trạng thái vào một biến và sử dụng nó làm chỉ mục để gọi một thủ tục (không giống như một GOTO được tính toán?) Cho mã rõ ràng / nhanh hơn so với sử dụng bộ đếm chương trình là trạng thái FSM. Tôi không ủng hộ đây là giải pháp tốt nhất trong hầu hết các trường hợp, chỉ là giải pháp tốt nhất trong một số trường hợp. Mở rộng tâm trí của bạn để tiếp cận thay thế.
MZB

5
@MZB, bạn có đồng ý rằng một lệnh gọi hàm cũng chỉ là một GOTO được tính toán không? Tương tự với các cấu trúc for / while / if / other / switch, trong số các cấu trúc khác. Các nhà thiết kế ngôn ngữ trừu tượng thay đổi trực tiếp đến quầy chương trình vì một lý do. Không sử dụng goto.
riwalk

3
Trực tiếp thực hiện một stHRachine có lẽ là một antipotype. Có rất nhiều cách để có một máy trạng thái mà không thể hiện các trạng thái và chuyển tiếp theo nghĩa đen. ví dụ:import re
SingleNegationElimination

12

Những hy sinh chúng tôi thực hiện để làm cho mã có thể kiểm tra được

Tôi nhảy qua rất nhiều vòng để làm cho mã của mình có thể kiểm tra được, nhưng tôi không giả vờ rằng tôi sẽ không được lựa chọn. Tuy nhiên, tôi thường nghe mọi người thúc đẩy ý tưởng rằng đây là những "cách thực hành tốt nhất". Những thực tiễn này bao gồm (được viết bằng ngôn ngữ của .Net, nhưng cũng áp dụng cho các ngôn ngữ khác) :

  • Tạo giao diện cho mọi lớp. Điều này nhân đôi số lượng các lớp (tệp) để xử lý và sao chép mã. Vâng, lập trình giao diện là tốt, nhưng đó là những gì các nhà đầu cơ công khai / riêng tư được dùng cho.
  • Mỗi lớp không được khởi tạo khi khởi động cần một nhà máy. Rõ ràng, new MyClass()đơn giản hơn nhiều so với viết một nhà máy, nhưng bây giờ phương pháp tạo ra nó không thể được kiểm tra một cách cô lập. Nếu không phải vì thực tế này, tôi sẽ chỉ tạo ra 1/20 số lượng nhà máy mà tôi làm bây giờ.
  • Làm cho mọi lớp trở nên công khai, trong đó đánh bại mục đích có các trình xác định truy cập trên các lớp. Tuy nhiên, các lớp không công khai không thể được truy cập (và do đó, đã được kiểm tra) từ các dự án khác, vì vậy lựa chọn duy nhất khác là chuyển tất cả mã kiểm tra sang cùng một dự án (và do đó phát hành nó với sản phẩm cuối cùng).
  • Phụ thuộc tiêm. Rõ ràng phải cung cấp cho mọi lớp khác tôi sử dụng một trường và tham số hàm tạo là công việc nhiều hơn đáng kể so với việc chỉ tạo chúng khi tôi cần chúng; nhưng sau đó tôi không còn có thể kiểm tra lớp này trong sự cô lập.
  • Nguyên tắc trách nhiệm duy nhất, khiến tôi rất đau đầu, tôi đã chuyển nó sang câu trả lời của riêng mình .

Vậy chúng ta có thể làm gì để khắc phục điều này? Chúng ta cần một sự thay đổi mạnh mẽ trong kiến ​​trúc ngôn ngữ:

  • Chúng tôi cần khả năng để chế giễu các lớp
  • Chúng tôi cần khả năng kiểm tra các phương thức riêng của các lớp bên trong, từ một dự án khác (điều này có vẻ như là một lỗ hổng bảo mật, nhưng tôi không thấy vấn đề gì nếu người kiểm tra buộc phải đặt tên cho các lớp thử nghiệm của nó) .
  • Tiêm phụ thuộc (hoặc vị trí dịch vụ), cũng như một cái gì đó tương đương với mẫu nhà máy hiện tại của chúng tôi, sẽ phải là một phần cốt lõi của ngôn ngữ.

Nói tóm lại, chúng ta cần một ngôn ngữ được thiết kế từ đầu với khả năng kiểm tra .


Tôi đoán bạn chưa bao giờ nghe nói về TypeMock ? Nó cho phép chế nhạo các lớp học, tư nhân, thống kê (nhà máy), bất cứ điều gì.
Allon Guralnek

@ ALLon: Tôi có, nhưng nó không phải là miễn phí , làm cho nó không phải là một lựa chọn cho hầu hết mọi người.
BlueRaja - Daniel Pflughoeft

Nếu bạn phải viết nhiều lớp xuất xưởng thì bạn đã làm sai điều gì đó. Các thư viện DI thông minh (ví dụ Autofac cho C #) có thể sử dụng Func <T>, Lazy <T>, Delegates, v.v. cho các nhà máy, mà không cần tự viết bất kỳ bản tóm tắt nào.
gix

10

Tách các ứng dụng thành Tiers; Lớp dữ liệu, lớp nghiệp vụ, lớp UI

Lý do chính mà tôi không thích điều này là hầu hết các nơi theo phương pháp này, sử dụng các khung rất dễ vỡ để hoàn thành nó. Lớp giao diện người dùng IE được mã hóa bằng tay để đối phó với các đối tượng của lớp nghiệp vụ, các đối tượng của lớp nghiệp vụ được mã hóa bằng tay để xử lý các quy tắc và cơ sở dữ liệu kinh doanh, cơ sở dữ liệu là SQL và khá dễ vỡ và được quản lý bởi nhóm "DBA" không thích thay đổi.

Tại sao điều này là xấu? Yêu cầu nâng cao phổ biến nhất có thể là "Tôi cần một trường trên màn hình X có Y." Bang! Bạn chỉ có một tính năng mới ảnh hưởng đến từng lớp và nếu bạn tách các lớp với các lập trình viên khác nhau, nó sẽ trở thành một vấn đề lớn liên quan đến nhiều người và nhóm, vì một sự thay đổi rất đơn giản.

Ngoài ra, tôi không biết đã bao nhiêu lần tôi tranh cãi với nhau như thế này. "Trường tên được giới hạn ở độ dài tối đa là 30, đây có phải là lớp UI hay lớp nghiệp vụ hay lớp dữ liệu không?" Và có một trăm lập luận, và không có câu trả lời đúng. Câu trả lời là như nhau, nó ảnh hưởng đến tất cả các lớp, bạn không muốn làm cho UI bị câm và phải trải qua tất cả các lớp, và thất bại tại cơ sở dữ liệu, vì vậy người dùng phát hiện ra mục nhập của mình quá dài. Nếu bạn thay đổi nó, nó sẽ ảnh hưởng đến tất cả các lớp, v.v.

Các "lớp" cũng có xu hướng rò rỉ; Nếu bất kỳ lớp nào được phân tách vật lý bởi các ranh giới quy trình / máy (UI web IE và logic phụ trợ kinh doanh), các quy tắc sẽ được sao chép để làm cho mọi thứ hoạt động hợp lý. Tức là một số logic kinh doanh kết thúc trong UI, mặc dù đó là "quy tắc kinh doanh", bởi vì người dùng cần UI để đáp ứng.

Nếu khung được sử dụng, hoặc kiến ​​trúc được sử dụng, có khả năng phục hồi các thay đổi và rò rỉ nhỏ, tức là dựa trên dữ liệu meta và được điều chỉnh động qua tất cả các lớp, nó có thể ít gây đau đớn hơn. Nhưng hầu hết các khung công tác này là một nỗi đau của hoàng gia, đòi hỏi thay đổi giao diện người dùng, thay đổi lớp nghiệp vụ và thay đổi cơ sở dữ liệu, cho mỗi thay đổi nhỏ, và gây ra nhiều công việc hơn và ít trợ giúp hơn so với kỹ thuật được cho là tạo ra.

Tôi có thể sẽ bị đánh sập vì điều này, nhưng nó đây :)


+1, có vẻ như là nơi làm việc cuối cùng của tôi đến từng chi tiết nhất! Tôi tôn trọng các ứng dụng theo nguyên tắc tuy nhiên có quá nhiều người coi nó như viên đạn bạc khi nó không có ý nghĩa. Hầu hết các phần mềm kinh doanh có số lượng logic kinh doanh thấp đáng kinh ngạc và những gì nó có là tương đối đơn giản. Điều này có thể làm cho logic kinh doanh phân lớp trở thành cơn ác mộng của mã soạn sẵn. Nhiều lần các dòng có thể bị mờ giữa truy cập dữ liệu và logic nghiệp vụ vì truy vấn là logic nghiệp vụ.
maple_shaft

... Hơn nữa, hầu hết các cửa hàng hoàn toàn thất bại trong việc nhận ra logic UI hoặc logic Trình bày. Vì họ không hiểu làm thế nào ít logic kinh doanh tồn tại trong một ứng dụng CRUD điển hình, nên họ cảm thấy như họ phải làm gì đó sai khi phần lớn logic của họ nằm trong lớp trình bày dưới dạng logic trình bày. Nó được xác định sai là logic kinh doanh và sau đó mọi người đẩy nó đến máy chủ để thực hiện một cuộc gọi máy chủ khác. Một khách hàng mỏng có thể và nên có logic Trình bày, vd. (Ẩn textField2 nếu tùy chọn1 được chọn trong dropDown3).
maple_shaft


7

Câu chuyện của người dùng / Trường hợp sử dụng / Personas

 

Tôi hiểu sự cần thiết của những điều này khi bạn lập trình cho một ngành mà bạn không quen thuộc, nhưng tôi nghĩ rằng khi chúng được thực thi đầy đủ, chúng trở nên quá tập thể và trở nên lãng phí thời gian.


7

Giới hạn 80 char / dòng là câm

Tôi hiểu rằng một số thỏa hiệp cần phải được thực hiện để phù hợp với tốc độ của người chạy chậm nhất về phía GUI (giới hạn độ phân giải màn hình, v.v.), nhưng tại sao quy tắc đó lại áp dụng cho định dạng mã?

Xem ... Có một phát minh nhỏ được gọi là thanh cuộn ngang được tạo ra để quản lý không gian màn hình ảo bên ngoài ranh giới pixel bên phải nhất. Tại sao các nhà phát triển, những người đã quản lý để tạo ra các công cụ nâng cao năng suất tuyệt vời như tô sáng cú pháp và tự động hoàn thành sử dụng nó?

Chắc chắn, có những biên tập viên CLI được sử dụng một cách tôn giáo bởi những con khủng long * nix tuân theo những hạn chế cũ mệt mỏi của các thiết bị đầu cuối VT220 của họ, nhưng tại sao phần còn lại của chúng tôi được giữ theo cùng tiêu chuẩn?

Tôi nói, vít giới hạn 80 char. Nếu khủng long đủ sử thi để hack emacs / vim cả ngày, tại sao không thể có khả năng tạo tiện ích mở rộng tự động bao bọc các dòng hoặc cung cấp khả năng cuộn ngang cho IDE CLI của chúng?

Màn hình 1920x1080 pixel cuối cùng sẽ trở thành chuẩn mực và các nhà phát triển trên toàn thế giới vẫn đang phải chịu những hạn chế tương tự mà không hiểu tại sao họ làm ngoại trừ, đó là những gì họ đã nói với những người lớn tuổi khi họ mới bắt đầu lập trình.

Giới hạn 80 char không phải là một thực tiễn tốt nhất mà là một thực tiễn thích hợp cho rất ít lập trình viên và nên được đối xử như vậy.

Biên tập:

Có thể hiểu rằng nhiều nhà phát triển không thích thanh cuộn ngang vì nó yêu cầu cử chỉ chuột nên ... Tại sao không tăng giới hạn chiều rộng cột lên số cao hơn (hơn 80) đối với những người sử dụng màn hình hiện đại.

Khi màn hình máy tính 800x600 trở thành tiêu chuẩn cho hầu hết người dùng, các nhà phát triển web đã tăng độ rộng trang web của họ để phù hợp với đa số ... Tại sao các nhà phát triển không thể làm như vậy.


1
@Hoàn động logic GWB đẹp với ___ là góc ác. Vì vậy, bạn không ưa hScroll, bạn có bất kỳ lý do hợp lệ nào tại sao độ rộng col nên được giới hạn ở 80 ký tự không? Tại sao không phải 160 hay 256? Tôi nghĩ rằng tất cả chúng ta đều có thể giả định rằng hầu hết các nhà phát triển đã nghỉ hưu các thiết bị đầu cuối VT220 của họ và thay thế chúng bằng puTTY để họ có thể mở rộng chiều rộng theo chương trình.
Evan Plaice

4
Tôi thích rằng chúng tôi tuân theo giới hạn 80 char. Ngay khi bạn cho tôi thêm không gian ngang, tôi sẽ cố gắng mở các tài liệu bổ sung song song với phần còn lại. Tôi ghét phải cuộn bốn cách. Ngoài ra, tôi thường nhận thấy rằng tôi buộc phải viết mã dễ đọc hơn với giới hạn 80 char.
Filip Dupanović

2
bạn sẽ in nó như thế nào?

5
Xin lỗi - phải không đồng ý về điều này. Tôi thực sự ghét những hàng dài - nó đòi hỏi nhiều chuyển động của mắt hơn, nó đòi hỏi cử chỉ của chuột để di chuyển qua, khó hơn để nhìn thấy những thứ nhỏ bé một cách tinh vi ở cuối dòng. Trong khoảng 99% trường hợp, có những cách rõ ràng để làm cho công cụ chạy trên một số dòng (ngắn hơn) rõ ràng và dễ đọc hơn. 80 Chars có thể là tùy ý và "bởi vì đó là như vậy trong những ngày thẻ bài" nhưng nó vẫn là một khuôn khổ hợp lý để làm việc bên trong - hầu hết thời gian - vì những lý do trên.
quick_now

3
Thụt lề bởi 2 khoảng trắng. Và sử dụng một trình soạn thảo với một trình theo dõi thụt tự động. Tôi đã làm theo cách đó trong nhiều năm, không có vấn đề gì lớn. (Emacs với các chế độ phù hợp sẽ giúp ở đây.)
quick_now

5

Đo lường, đo lường, đo lường

Rất tốt, đo lường đi, nhưng để cô lập các lỗi hiệu suất, đo lường hoạt động cũng như loại bỏ liên tiếp. Đây là phương pháp tôi sử dụng.

Tôi đã cố gắng truy tìm nguồn gốc của "trí tuệ" đo lường. Ai đó với một hộp xà phòng đủ cao nói điều đó, và bây giờ nó đi du lịch.


5

Giáo viên của tôi yêu cầu tôi bắt đầu tất cả các định danh của mình (không bao gồm các hằng số) bằng các chữ cái viết thường, ví dụ myVariable.

Tôi biết nó có vẻ như là một điều nhỏ, nhưng nhiều ngôn ngữ lập trình yêu cầu các biến để bắt đầu bằng chữ in hoa. Tôi coi trọng tính nhất quán, vì vậy đó là thói quen của tôi để bắt đầu mọi thứ bằng chữ in hoa.


9
Tôi đã có một giáo viên yêu cầu camelCase vì anh ấy khăng khăng rằng đó là những gì mọi người sử dụng trong thế giới thực ... Đồng thời tôi đang lập trình trong hai nhóm khác nhau trong công việc của mình - cả hai nhóm đều khăng khăng đòi hỏi. Điều quan trọng là những gì nhóm của bạn sử dụng. Anh ta có thể tự xác định mình là lập trình viên chính và tất cả sẽ ổn trong cuốn sách của tôi - chúng tôi tuân theo quy ước của anh ta - nhưng anh ta luôn đưa ra ý kiến ​​của mình là "cách mọi thứ được thực hiện trong thế giới thực" như thể không có giá trị nào khác đường.
xnine

@xnine Tôi chưa có đủ đại diện trên trang này để đánh giá bình luận của bạn, vì vậy tôi sẽ chỉ trả lời với nhận xét
Tối đa

5
Trường hợp lạc đà (chữ thường chữ thường) là một quy ước khá phổ biến cũng như trường hợp Pascal (chữ cái đầu tiên của mỗi từ viết hoa). Trong hầu hết các ngôn ngữ, camelCase được sử dụng trên các biến riêng tư / nội bộ trong đó PascalCase được sử dụng trên các lớp, phương thức, thuộc tính, không gian tên, biến công khai. Đó là một thực tế không tồi để làm quen với việc sẵn sàng cho các dự án có thể sử dụng một sơ đồ đặt tên khác.
Evan Plaice

2
Chỉ là một FYI. Một số ngôn ngữ suy ra ý nghĩa từ chữ cái đầu tiên của biến có phải là vốn hay không. Trong một ngôn ngữ như vậy, nếu chữ cái đầu tiên viết hoa, biến được coi là hằng số - mọi nỗ lực thay đổi nó sẽ gây ra lỗi.
Berin Loritsch

1
Trong Go , các phương thức công khai và các thành viên trong các lớp bắt đầu bằng một chữ cái viết hoa; những người riêng tư với một chữ cái viết thường.
Jonathan Leffler

5

Sử dụng Singletons

Khi bạn chỉ nên có một ví dụ của một cái gì đó. Tôi không thể không đồng ý nhiều hơn. Không bao giờ sử dụng một singleton và chỉ phân bổ nó một lần và chuyển xung quanh con trỏ / đối tượng / tham chiếu khi cần thiết. Hoàn toàn không có lý do để không làm điều này.


2
Đó là cả một loạt những tiêu cực khiến tôi khá bối rối về lập trường thực sự của bạn đối với những người độc thân.
Paul Butcher

1
@Paul Butcher: Tôi ghét singletons và nó không bao giờ nên được sử dụng

1
@rwong: Cá nhân tôi không nghĩ lý do nào là lý do chính đáng. Chỉ cần viết nó như một lớp học bình thường. Thực sự, không có lý do để sử dụng một singleton khác sau đó lười biếng và để thúc đẩy các thói quen hoặc thiết kế xấu.

6
Ai nói rằng sử dụng Singeltons là cách tốt nhất?
Phil Mander

2
Singletons có vị trí của mình, đặc biệt là trong trường hợp cấu trúc hoạt động được phân bổ và điền vào khi khởi động, sau đó về cơ bản chỉ được đọc trong suốt thời gian chạy chương trình. Trong trường hợp đó, nó chỉ trở thành một bộ đệm ở phía bên kia của một con trỏ.
Tim Post

5

Sử dụng unsign int như iterator

Khi nào họ sẽ biết rằng sử dụng int đã ký sẽ an toàn hơn và ít bị lỗi hơn. Tại sao điều quan trọng là chỉ số mảng chỉ có thể là số dương, mà mọi người đều vui mừng bỏ qua thực tế rằng 4 - 5 là 4294967295?


Được rồi, bây giờ tôi tò mò - tại sao bạn nói vậy? Tôi cảm thấy hơi ngu ngốc - bạn có thể cung cấp một số ví dụ mã để sao lưu các báo cáo của mình không?
Paul Nathan

4
@Paul Nathan: theo như lỗi thì đây là một ví dụ: for (unsign int i = 0; i <10; i ++) {int crash_here = my_array [max (i-1,0)];}
AareP

@AareP: Để chắc chắn - Tôi cho rằng bạn đang tham khảo thực tế rằng khi một số nguyên không dấu 0bị giảm 1, bạn thực sự kết thúc với giá trị dương tối đa mà một số nguyên không dấu có thể lưu trữ?
Adam Paynter

1
@Adam Paynter: có. Điều này có vẻ bình thường đối với các lập trình viên c ++, nhưng chúng ta hãy đối mặt với nó, "unsign int" là một "triển khai" xấu của các số chỉ dương.
AareP

Không phải là một ý tưởng tốt trên các máy nhúng nhỏ - ints không dấu thường xuyên sẽ tạo ra mã nhỏ hơn, nhanh hơn. Phụ thuộc vào trình biên dịch và bộ xử lý.
quick_now

4

Các phương thức không nên dài hơn một màn hình

Tôi hoàn toàn đồng ý với nguyên tắc trách nhiệm đơn lẻ nhưng tại sao mọi người lại cho rằng nó có nghĩa là "một chức năng / phương pháp có thể có nhiều hơn một trách nhiệm duy nhất ở mức độ chi tiết logic tốt nhất"?

Ý tưởng rất đơn giản. Một chức năng / phương thức nên hoàn thành một nhiệm vụ. Nếu một phần của chức năng / phương thức đó có thể được sử dụng ở nơi khác, hãy cắt nó thành chức năng / phương thức riêng của nó. Nếu nó có thể được sử dụng ở nơi khác trong dự án, hãy chuyển nó vào lớp riêng hoặc lớp tiện ích và làm cho nó có thể truy cập được trong nội bộ.

Có một lớp chứa 27 phương thức của trình trợ giúp chỉ được gọi một lần trong mã là ngu ngốc, lãng phí không gian, tăng độ phức tạp không cần thiết và thời gian chìm rất lớn. Nghe có vẻ giống như một quy tắc tốt cho những người muốn tìm mã tái cấu trúc bận rộn nhưng không sản xuất nhiều.

Đây là quy tắc của tôi ...

Viết hàm / phương thức để hoàn thành một cái gì đó

Nếu bạn thấy mình sắp sao chép / dán một số mã, hãy tự hỏi liệu có tốt hơn không khi tạo một hàm / phương thức cho mã đó. Nếu một hàm / phương thức chỉ được gọi một lần trong một hàm / phương thức khác, thì thực sự có một điểm trong việc có nó ở vị trí đầu tiên (nó sẽ được gọi thường xuyên hơn trong tương lai). Có giá trị khi thêm nhiều lần nhảy vào / ra các chức năng / phương thức trong quá trình gỡ lỗi không (nghĩa là bước nhảy được thêm vào giúp việc gỡ lỗi dễ dàng hay khó hơn)?

Tôi hoàn toàn đồng ý rằng các hàm / phương thức lớn hơn 200 dòng cần được xem xét kỹ lưỡng nhưng một số hàm chỉ hoàn thành một nhiệm vụ trong bao nhiêu dòng và không chứa các phần hữu ích có thể được trừu tượng hóa / sử dụng trên phần còn lại của dự án.

Tôi nhìn nó từ góc độ nhà phát triển API ... Nếu một người dùng mới nhìn vào sơ đồ lớp của mã của bạn, có bao nhiêu phần của sơ đồ đó sẽ có ý nghĩa trong toàn bộ dự án và có bao nhiêu tồn tại duy nhất như người trợ giúp cho các bộ phận khác nội bộ của dự án.

Nếu tôi chọn giữa hai lập trình viên: người đầu tiên có xu hướng viết các hàm / phương thức cố gắng làm quá nhiều; cái thứ hai phá vỡ mọi phần của mọi chức năng / phương pháp đến mức độ chi tiết tốt nhất; Tôi sẽ chọn tay đầu tiên xuống. Đầu tiên sẽ thực hiện được nhiều hơn (nghĩa là viết nhiều thịt hơn của ứng dụng), mã của anh ta sẽ dễ gỡ lỗi hơn (do ít nhảy vào / ra các chức năng / phương thức trong quá trình gỡ lỗi) và anh ta sẽ lãng phí ít thời gian hơn để hoàn thành công việc bận rộn mã trông vs hoàn thiện cách mã hoạt động.

Hạn chế trừu tượng không cần thiết và không gây ô nhiễm tự động hoàn thành.


Điều này. Tôi đã từng tái cấu trúc một số hàm dài thành nhiều hàm, chỉ để nhận ra rằng hầu hết tất cả chúng đều cần gần như tất cả các tham số của mã gốc. Việc xử lý tham số là một nỗi đau đến mức dễ dàng hơn để quay lại mã cũ.
l0b0

3
Tôi nghĩ rằng một đối số cho điều này là việc tái cấu trúc các phần của một phương thức lớn thành các lệnh gọi riêng biệt có thể làm cho phương thức lớn hơn dễ đọc hơn. Ngay cả khi phương thức chỉ được gọi một lần.
Jeremy Heiler

1
@Jeremy thế nào? Làm thế nào, trừu tượng hóa một phần của mã và đặt nó vào phương thức riêng của nó làm cho nó dễ đọc hơn là chỉ đặt một nhận xét một dòng ở đầu đoạn mã mô tả những gì nó làm? Giả sử rằng khối mã chỉ được sử dụng một lần trong phần mã đó. Là nó thực sự khó khăn đối với hầu hết các lập trình viên để phân hủy các bộ phận làm việc của mã trong khi họ đọc nó và / hoặc đặt một vài một dòng bình luận để nhắc nhở họ những gì nó làm nếu họ không thể?
Evan Plaice

4
@Evan: Đưa các đoạn mã vào các hàm một cách hiệu quả mang lại cho chúng một cái tên , hy vọng giải thích tốt về đoạn mã đó làm gì. Bây giờ, bất cứ nơi nào đoạn mã được gọi, bạn có thể thấy tên giải thích mã đó làm gì , thay vì phải phân tích và hiểu chính thuật toán. Nếu được thực hiện tốt, điều này có thể dễ dàng đọc và hiểu mã rất nhiều.
sbi

1
+1 và tôi sẽ cung cấp thêm nếu tôi có thể. Không có gì sai cả với một khối mã C có 1000 dòng trong một hàm duy nhất (ví dụ: trình phân tích cú pháp với một công tắc lớn ()) CUNG CẤP ý định rất rõ ràng và đơn giản. Phá vỡ tất cả các mảnh nhỏ ra và gọi chúng chỉ làm cho điều khó hiểu hơn. Tất nhiên cũng có giới hạn cho điều này .... phán đoán hợp lý là tất cả.
quick_now
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.