Chúng ta có nên khuyến khích các phong cách mã hóa theo hướng tự chủ của nhà phát triển, hay không khuyến khích nó theo hướng nhất quán?


15

Một nhà phát triển viết if/elsecác khối với các câu lệnh mã một dòng như:

if (condition)
   // Do this one-line code
else
   // Do this one-line code

Một cách khác sử dụng dấu ngoặc nhọn cho tất cả chúng:

if (condition) 
{
   // Do this one-line code
}
else
{
   // Do this one-line code
}

Trước tiên, một nhà phát triển khởi tạo một đối tượng, sau đó sử dụng nó:

HelperClass helper = new HelperClass();
helper.DoSomething();

Một nhà phát triển khác khởi tạo và sử dụng đối tượng trong một dòng:

new HelperClass().DoSomething();

Một nhà phát triển dễ dàng hơn với các mảng và forcác vòng lặp:

string[] ordinals = new string[] {'First', 'Second', 'Third'};
for (i = 0; i < ordinals.Length; i++)
{
    // Do something
}

Một người khác viết:

List<string> ordinals = new List<string>() {'First', 'Second', 'Third'};
foreach (string ordinal in ordinals)
{
    // Do something
}

Tôi chắc chắn rằng bạn biết những gì tôi đang nói về. Tôi gọi nó là phong cách mã hóa (vì tôi không biết nó được gọi là gì). Nhưng bất cứ điều gì chúng ta gọi nó, nó là tốt hay xấu? Có khuyến khích nó có ảnh hưởng đến năng suất cao hơn của các nhà phát triển? Chúng ta có nên yêu cầu các nhà phát triển cố gắng viết mã theo cách chúng ta nói với họ, để làm cho toàn bộ hệ thống trở nên nhất quán theo phong cách không?


1
Tôi thực sự đã đến đây để hỏi một câu hỏi tương tự ngay bây giờ - khi các công cụ định dạng mã tự động có sẵn và thuận tiện, điều quan trọng hơn là các công cụ đó không được chạy (và duy trì các kiểu cá nhân không nhất quán) hay để thực thi một kiểu?
lông mịn

Phong cách nhất quán làm cho việc đọc mã dễ dàng hơn, do đó sử dụng một phong cách nhất quán. Trong ví dụ của bạn, dễ đọc nhất là 2, 1, 2. Mặc dù trường hợp cuối cùng là khác nhau. Trong các ứng dụng quan trọng về hiệu năng, vòng lặp for sẽ nhanh hơn khi lặp qua các danh sách. Hiệu suất là lặp đi lặp lại trên các mảng. Và trong mọi trường hợp, sử dụng varthay vì tên loại đủ điều kiện.
Stephen

Câu trả lời:


19

Một tài liệu tiêu chuẩn mã hóa là hữu ích. Nó hữu ích nhất khi nó đủ ngắn để mọi người có thể nhớ toàn bộ mọi thứ mà không gặp quá nhiều rắc rối và khi nó không gây cho ai quá nhiều nỗi đau.

Cách bạn chọn thụt mã trong tổ chức của mình, hoặc viết hoa tên hoặc thực hiện các vòng lặp hoặc nhận xét mã của bạn không quan trọng lắm; phần hữu ích là khiến mọi người viết mã trông giống như mọi người khác.

  • Nó tránh việc phải dành một phút để tính toán lại kỳ vọng của bạn về vị trí niềng răng và mỗi lần bạn nhìn vào mã của người khác.
  • Nó tránh có một số kiểu mã khác nhau trong cùng một tệp.
  • Có lẽ quan trọng nhất, có một tiêu chuẩn bằng văn bản sẽ tránh được những tranh luận về thực hành mã hóa trong quá trình đánh giá mã.

Một lần nữa, những gì các tiêu chuẩn không quan trọng bằng việc có một số tiêu chuẩn đơn giản, đơn giản. Vì vậy, hãy đặt tất cả các nhà phát triển của bạn vào một căn phòng và để họ tranh luận về những tiêu chuẩn nên có. Cuộc họp này có thể diễn ra vô thời hạn, vì vậy các quy tắc là:

  • Bất cứ điều gì không được quyết định vào cuối cuộc họp sẽ được quyết định bởi người quản lý.
  • Cuộc họp sẽ kết thúc sau hai giờ, hoặc khi ai đó bắt đầu la hét hoặc khóc, tùy theo điều kiện nào đến trước.
  • Toàn bộ tiêu chuẩn sẽ phù hợp (với kích thước loại hợp lý!) Trên một hoặc hai tờ giấy, chỉ hai mặt nếu thực sự cần thiết.

Cân nhắc việc nhận nuôi ai đó | của người khác | các tiêu chuẩn hoặc là điểm khởi đầu cho cuộc họp tiêu chuẩn mã hóa của riêng bạn hoặc là một cách để tránh cuộc họp hoàn toàn.

Khi đã đồng ý, các nhà phát triển sẽ có thể (và nên được mong đợi) chính cảnh sát. Sự sai lệch đôi khi so với tiêu chuẩn không phải là một vấn đề lớn (và thậm chí có thể chính đáng), nhưng việc từ chối từ bỏ một số phong cách cá nhân yêu thích theo tiêu chuẩn sẽ dẫn đến việc di chuyển ngay đến văn phòng với các ống nước bị rò rỉ, hoặc bất cứ điều gì .

Demian Brecht chỉ vào các công cụ lint. Đây là một bổ sung hoàn hảo cho một tài liệu tiêu chuẩn mã hóa. Nó chỉ tốt để tuân theo các tiêu chuẩn phong cách mã hóa ; điều quan trọng là phải tuân thủ các tiêu chuẩn mã hóa liên quan đến các thực hành nguy hiểm. Không ai khác ngoài tác giả sẽ kiểm tra xem mọi dòng mã có đáp ứng tiêu chuẩn cho kiểu dáng hay không, nhưng bạn chắc chắn nên xem xét việc xây dựng một công cụ lint vào quy trình làm việc của nhóm để tự động bắt lỗi. Ngoài ra, bản thân công cụ có thể mã hóa các thực tiễn được chấp nhận để bạn không phải liệt kê tất cả chúng theo các tiêu chuẩn mã hóa; chỉ cần xác định cấu hình của công cụ.

Lưu ý: Ý tưởng "tiêu chuẩn mã hóa" không phải là duy nhất cho lập trình. "Tiêu chuẩn mã hóa" được sử dụng trong nhiều lĩnh vực, đôi khi trong một tổ chức, thường xuyên hơn trong toàn bộ ngành hoặc nghề. Vài ví dụ:

Trong mỗi trường hợp (và nhiều người khác), một học viên có năng lực có thể dễ dàng hiểu "mã" không đáp ứng tiêu chuẩn dự kiến. Tại sao nhiều ngành công nghiệp vẫn tồn tại trong việc viết các yêu cầu chi tiết cho các tài liệu thậm chí không cần phải được phân tích cú pháp bởi trình biên dịch? Bởi vì vấn đề phong cách . Trình bày thông tin theo phong cách chuẩn cho phép người đọc tập trung hoàn toàn vào nội dung, giúp đọc nhanh hơn và giúp hiểu và giảm lỗi.


1
Nếu bạn thêm việc sử dụng các công cụ linting vào bài đăng của mình, tôi sẽ xóa của tôi và +1 của bạn :)
Demian Brecht

@D bohBrecht, đề nghị tốt, cảm ơn. Đã thêm các công cụ lint để cải thiện câu trả lời của tôi, nhưng tôi nghĩ bạn cũng nên để lại câu trả lời của mình.
Caleb

Thôi được rồi. +1 dù sao :)
Demian Brecht

Và cũng cho bạn!
Caleb

+1 cho "... di dời ngay lập tức ..." như theo kinh nghiệm của tôi, hành vi đó phù hợp với xu hướng xã hội học và / hoặc tự ái, không tương thích với các nhóm phát triển phần mềm.
mattnz

16

Phong cách không thành vấn đề.

Ở đó, tôi đã nói nó.

Sau 30 năm và hàng trăm trang web của khách hàng và mã từ (ước tính) 500 (hoặc nhiều hơn) thành viên nhóm trong những năm đó, tôi đã thấy rằng phong cách đó không thành vấn đề.

Làm cho nó hoạt động, đầu tiên.

Làm cho nó sử dụng một khối lượng tài nguyên tối ưu (nghĩa là cấu trúc dữ liệu đúng, thuật toán đúng).

Băn khoăn về "phong cách" sau khi mọi thứ khác đã được giải quyết. Fuss của "phong cách" chỉ với các công cụ, không bao giờ bằng tay.


2
Amen! Các tiêu chuẩn mã hóa cần phải được chứng minh về mặt lợi ích thực sự và tính nhất quán không phải là lợi ích thực sự, mà là một sự xa xỉ.
JohnFx

12
Nhưng phong cách hiếm khi về phong cách. Đó là về việc tránh các lỗi phổ biến.
Martin York

6
Nhưng nó giúp tránh '=' thay vì '==' (không sử dụng phép gán trong điều kiện). Nó giúp tránh if (t) { x;y;}hơn là if (t) x;y;(luôn luôn sử dụng '{}' sau nếu). Thích mã const const (rất khó để thêm const constness vào mã sau khi nó được viết. Sử dụng std :: cout / std :: cin không fprintf / scanf trước đây có nhiều khả năng gây ra lỗi hơn. Sử dụng vector thay vì mảng (để giúp ngăn tràn).
Martin York

5
Làm cho nó hoạt động rõ ràng là tối quan trọng. Nhưng chỉ vì nó hoạt động không có nghĩa là nó đã hoàn thành. Nó cũng cần phải được thử nghiệm. Và sau đó xem xét. Tất cả có thể mất vài ngày. Sau đó, trong nhiều năm sau đó, nó phải được đọc và hiểu và duy trì. Mã hữu ích (tại sao viết bất kỳ loại nào khác?) Sẽ được đọc nhiều lần hơn so với mã được viết, do đó giúp dễ đọc và hiểu cải thiện năng suất trong tương lai. Sử dụng một phong cách nhất quán trong toàn tổ chức là một cách để giúp về mặt đó.
Caleb

1
Điều gì về việc thực thi việc sử dụng các công cụ định dạng tự động? Eclipse và XCode làm cho việc giữ định dạng mã rất dễ dàng - nhưng một trong những kỹ sư mà tôi làm việc rất khó chịu nếu ai đó tự động định dạng mã "của mình" (tức là của công ty) để giữ cho nó phù hợp với phần còn lại của cơ sở mã. Định dạng chỉ là một phần nhỏ của phong cách nhưng nó cũng là một phần quan trọng, đặc biệt đối với các vấn đề như nếu / khác lồng và dòng mã tổng thể (không đề cập đến khả năng đọc).
lông mịn

4

Có phong cách mã hóa và có mùi mã hóa. Đó là một lần mà tôi đã tìm thấy:

    if(debugCondition)
//         printf("DEBUG: state:%s at debugCondition\n",dbg_state());

    for(i=0; i<MAX;i++)
    {
       //some essential business logic
    }

Chủ nhân trước đây của tôi đã nghiêm cấm sử dụng multiline if()mà không cần niềng răng. Nó được coi là lỗi loại "làm lại và bạn bị sa thải". Các cấu trúc được phép là

     if(condition) break; 
     if(condition) continue; 
     if(condition) return; 
     if(condition) for()...; 

Điều này dẫn đến một lỗi giống như lỗi tôi đã trình bày ở trên, mất vài giờ để tìm cách đưa trang chính của cổng thông tin dừng lại.

Có những điều bạn chỉ nên luôn luôn làm. Giống như switch():

     case 1:
         something();
     break;
     case 2:
         something();
     return;
     case 3:
         something();
     continue;
     case 4:
     case 5:
         something();
     break;
     case 6:
         something();
     //fallthrough;
     case 7:
     ...

Trong khi đó, gõ:

     case 1:
         something();
     case 2:
         something();
     break;

mà không đóng a casevới //fallthroughđược coi là một lỗi.

Nói chung, có tiêu chuẩn mã hóa là hướng dẫn có thể bỏ qua, diễn giải sáng tạo hoặc sửa đổi cho các nhu cầu nhất định. Và có phần "mùi" và nó phải được tuân thủ nghiêm ngặt.


3

Tạo sự nhất quán với một thiết kế trả trước tốt. Những gì bạn mô tả trong câu hỏi không gì khác hơn là quản lý vi mô. Tôi làm rất nhiều việc phát triển web. Vì vậy, tôi ủng hộ phát triển RESTful và CRUD tiếp xúc như các dịch vụ. Điều này đảm bảo các thực thể đơn giản, được xác định rõ có thể được sử dụng theo nhiều cách khác nhau.

Thiết kế này cũng cho phép tôi ủy thác chi tiết triển khai cho các nhà phát triển khác. Bằng cách này, họ đang điền vào chỗ trống thay vì tạo ra một thiết kế toàn bộ hệ thống.

Việc thiếu một thiết kế tổng thể tạo ra sự không nhất quán hệ thống. Phê bình về các bước lặp cơ bản và các cấu trúc lặp không làm cải thiện thiết kế hệ thống. Những loại vấn đề này được giải quyết tốt hơn với cách tiếp cận thực tế, StyleCop.

Bạn có thể vẽ một sơ đồ tương đối đơn giản của thiết kế hệ thống tổng thể của bạn? Một thiết kế mô tả các yếu tố / thực thể liên quan đến một nhà phát triển nhóm mới. Nếu bạn không thể, hoặc nó có liên quan cao thì thiết kế thiếu.


3

IMHO nó phụ thuộc ...

Hai ví dụ đầu tiên của bạn không chỉ là vấn đề sở thích cá nhân với tôi.

if (condition)
   // Do this one-line code
else
   // Do this one-line code

(không có dấu ngoặc) = dễ bị lỗi hơn, nếu thêm mã sau này vào sau:

if (condition)
   // Do this one-line code
else
   // Do this one-line code
   // ...and this line as well... oops! this will actually execute either way

Và điều này ít thuận tiện hơn để gỡ lỗi:

new HelperClass().DoSomething(GetSomeData()); // etc.

Bạn không thể chỉ cần đặt một điểm dừng mà bạn cần nó. Nếu đây là một lần - đủ công bằng, nhưng chúng tôi thảo luận nó là vấn đề về phong cách, và một khi bạn đã có những thứ như thế này ở khắp mọi nơi, việc gỡ lỗi trở nên khó chịu hơn nó phải có.

Đối với ví dụ thứ ba của bạn (đối với vs foreach), tôi thấy đó là vấn đề của hương vị.


2

Cũng không. Tôi sẽ tránh các quy tắc mã hóa khắc nghiệt để tránh tẻ nhạt, kén chọn, quản lý vi mô và tệ nhất là lãng phí thời gian. Ý thức tự chủ của bạn là vấn đề của riêng bạn. Nếu tôi muốn bạn cảm thấy tốt hơn về bản thân, tôi sẽ mua cho bạn một ly đồ uống yêu thích của bạn. Ngoài ra, hãy hoàn thành công việc.


2

Sử dụng các quy ước, tên biến, tên lớp, vv là thực hành tốt. Nhưng các kiểu mã hóa như các ví dụ bạn cung cấp khá tầm thường và không ảnh hưởng đến khả năng đọc hoặc hiệu quả của mã. Mặt khác, chi phí từ việc thực thi một kiểu nhất định kết hợp với nỗ lực của các nhà phát triển để tuân theo nó sẽ gây ra vấn đề.


2

Sử dụng một công cụ linting tiêu chuẩn công nghiệp (rõ ràng là FxCop cho C #). Mặc dù nó không phải là cuối cùng, nhưng tất cả, tính nhất quán rất quan trọng trong các dự án lớn có một số người làm việc với chúng.

Nếu bạn chỉ làm việc trong dự án của riêng bạn hoặc nhóm nhỏ, nhiều người sẽ cho rằng đó là quá mức cần thiết. Tôi tin khác (tôi sử dụng PEP8 cho Python, ngay cả trong các dự án nhà phát triển cá nhân của tôi).

Tuy nhiên, hầu hết các ví dụ bạn đưa ra rất có thể sẽ không bị bắt bởi một công cụ linting vì chúng đơn giản là không quan trọng.


1

Thực thi phong cách mã hóa thống nhất luôn luôn khó khăn. Lý tưởng nhất là nhiệm vụ trần tục như vậy nên để lại một công cụ để xử lý. Tôi hoan nghênh cộng đồng ngôn ngữ Go đã làm điều đó.


1

Đó là một hỗn hợp của cả hai. Chỉ vì đó là một tiêu chuẩn không làm cho nó có thể đọc và duy trì được. Nếu chưa có tiêu chuẩn thấm nhuần, hoặc có những khía cạnh bị lỗi và không thể đọc được của nó, sửa đổi là phù hợp.


1

Trong phân tích cuối cùng, đó là lập trình viên điều khiển chương trình. Các vấn đề về phong cách tồn tại, nhưng chúng là thứ yếu để đưa chương trình ra ngoài.

Nó rất hữu ích để cung cấp cho các lập trình viên MỘT SỐ hướng dẫn phong cách. Điều này có thể / nên được thực hiện trước khi các lập trình viên được đưa vào làm việc, đặc biệt nếu họ là những người mới bắt đầu tương đối với môi trường hoặc để tự lập trình. Được hướng dẫn, một số lập trình viên sẽ rất có ý thức về phong cách, những người khác thì ít hơn. Hướng dẫn được đưa ra khi bắt đầu dự án sẽ giúp nhóm lập trình viên đầu tiên, từ đó làm cho nhiệm vụ tổng thể dễ dàng hơn. Nó có thể làm rất ít cho nhóm thứ hai, hy vọng sẽ tạo nên sự sáng tạo, những gì họ thiếu trong sự phù hợp.


1

Tôi nghĩ rằng nó thuộc về quy mô của dự án và có bao nhiêu người đang làm việc với nó. Một lập trình viên lành nghề có thể nhìn vào cả hai phong cách định dạng khác nhau và biết những gì đang diễn ra trong cả hai phong cách đó, nhưng cần phải có một sự đồng thuận để mắt có thể dễ dàng nắm bắt nó. Nếu bạn định thực hiện một dòng duy nhất mà không cần niềng răng thì dự án đó không nên sử dụng chúng Ai đã từng dẫn dắt dự án đó nên có lựa chọn đó. Tôi thích những thứ nhìn rõ ràng và cũng rất nhỏ gọn vì tôi có thể có được chúng. Nếu bạn sẽ tạo một dòng duy nhất nếu statmeents họ trông tốt hơn như thế này

if() {}
else() {}

Hoặc thậm chí:

if() {} else () {}

Nhưng một dòng duy nhất nếu không nên sử dụng khoảng cách của một mulitiline nếu. Nó chỉ là cách tôi làm mọi thứ. Tôi không quan tâm đến cách gọi đối tượng và điều đó phụ thuộc vào số lần gọi của nó. Nếu nó được gọi một vài lần thì tôi nên khởi động đối tượng và tùy thuộc vào việc nó có các cuộn dây hay không và cái gì cũng không. Bởi vì nếu bạn có một hàm tạo và bạn gọi:

Object.method();
Object.method2();

Sau đó, bạn đã kết thúc cuộc gọi phương thức bộ tạo đối tượng hai lần khi nó có thể tránh được bằng cách tạo ra đối tượng đầy đủ.

Khi nói về foreach và cho các vòng lặp Cũng về lan truyền, một số làn đường cho phép bạn kiểm soát tốt hơn khi nhìn vào mảng trong một vòng lặp foreach để bạn có khóa và giá trị trong mảng tạm thời. Và tôi biết một số làn đường có một số loại tối ưu hóa bởi vì họ có thể nhìn vào vòng lặp và biết chính xác số lần nó sẽ được gọi.


1

Mặc dù ví dụ đầu tiên của bạn không tuyệt vời (lập luận rằng nó dễ bị lỗi hơn khi sửa đổi mang một số trọng lượng), nói chung tôi thực sự đã phát triển để thích các nhà phát triển sử dụng các kiểu mã hóa hơi khác nhau.

Sau khi làm việc với mã của các thành viên khác trong nhóm, đôi khi chỉ trong vài tháng, về cơ bản, nó bắt đầu hoạt động theo dòng git blame. Sau khi ở công ty tôi hơn 10 năm, tôi có thể nói với bạn với độ chính xác hơn 80%, người đã viết bất kỳ lớp nào ở bất cứ đâu trong 500k dòng mã của chúng tôi, chỉ bằng cách nhìn vào nó.

Mặc dù có một chút "thời gian lan man" khi bạn bắt đầu xem mã sử dụng kiểu mà bạn không đồng ý, nhưng điều bạn thực sự làm trong thời gian đó là nói "ồ, đây giống như mã của John Doe (bởi vì anh ta sử dụng kiểu X nhưng không phải kiểu Y, v.v.) ". Và điều đó mang lại cả một đống bối cảnh. Với một xấp xỉ đầu tiên, bạn biết những gì mong đợi từ mã của John - những phần khác của cơ sở mã mà anh ấy hiểu rõ và những phần anh ấy không làm, cho dù anh ấy là một chuyên gia SQL hay người mới làm GUI, v.v.

Chạy mã của mọi người thông qua một trình định dạng về cơ bản loại bỏ thông tin này, ẩn nó phía sau một git blame, mà bạn có thể không bận tâm để chạy.


0

Điều này thực sự phụ thuộc rất nhiều vào loại hình tổ chức.

Nếu bạn là một nhóm nhỏ các siêu anh hùng, thì bất kỳ loại phong cách nào cũng tốt. Nếu mọi người đều có phong cách riêng của họ, và cả hai đều tốt và phù hợp với nội bộ, thì đó là tất cả quá trình bạn cần. Các siêu anh hùng sẽ nói: "Jane có dấu ngoặc, vì vậy đây là ý của cô ấy" hoặc "Jack sử dụng camelCase cho các biến".

Các tiêu chuẩn phổ quát có xu hướng tốt nhất để biến mọi người thành người chơi B +. Các siêu anh hùng của bạn sẽ bị kéo xuống bởi điều này. Nhưng nếu bạn muốn một người chơi A và nửa tá người chơi B và nửa tá người chơi C trung bình lên đến B +, thì bạn muốn có các tiêu chuẩn phù hợp. Trong trường hợp này, bạn muốn mọi người làm mọi thứ giống nhau để người chơi A có thể duyệt mã của mọi người nhanh nhất có thể.

Nhiều bạn nói, "Nhưng đợi đã, tại sao không bỏ đi với người chơi B và C?"

Thực tế là không có nhiều siêu anh hùng. Mặc dù có thể trả tiền để tìm và nuôi dưỡng chúng tại Google, nhưng việc đưa vào một hệ thống thanh toán mới cho Ma Bell có thể hiệu quả hơn về chi phí với nhóm sau. (Và nếu bạn thực sự có Siêu anh hùng, 4 hoặc 5 người trong số họ sẽ đắt gấp đôi so với hàng tá đàn em)

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.