Coding standard là gì

Coding Convention là chuẩn mực và quy tắc để code, các lập trình viên trong 1 dự án phải tuân theo - tương tự như quy tắc soạn văn bản cần có quy tắc canh lề, quy tắc chữ to nhỏ, đậm nhạt.

Xa hơn nữa, các dự án lớn đòi hỏi đồng bộ giữa các thành viên với nhau là cần thiết, các chuẩn mực sẽ giúp cho các lập trình viên cùng có cách hiểu, cùng nhìn về một hướng, tối ưu thời gian đọc code.

Coding Convention trong bài viết dành cho một số ngôn ngữ họ C như: C, C++, C#, Java, JavaScript.

Các vấn đề khi khai báo biến

Cách đặt tên biến phải mang nghĩa nhất định

Xét ví dụ:

ConvergedSins* ConvergedSins::createConvergedSins[Color a, int b] { ConvergedSins* ret = new ConvergedSins[]; if[ret && ret->init[a, b]] { ret->autorelease[]; return ret; } SAFE_DEL[ret]; return NULL; }

2 biến a và b được truyền vào hàm createConvergedSins không mang ý nghĩa. Có thể làm tốt hơn nếu thay a bởi color và b bởi level do trong ngữ cảnh này a và b mang 2 ý nghĩa đó.

ConvergedSins* ConvergedSins::createConvergedSins[Color color, int level] { ConvergedSins* ret = new ConvergedSins[]; if[ret && ret->init[color, level]] { ret->autorelease[]; return ret; } SAFE_DEL[ret]; return NULL; }

Sau khi thay đổi đoạn code như trên, khi bảo trì sẽ tránh mất thời gian tra cứu lại ý nghĩa của biến.

Tuy nhiên, không nhất thiết phải lúc nào cũng tuân theo quy tắc, nếu như 1 điều quá hiển nhiên:

int Add[int a, int b] { return a + b; }

Bảng liệt kê một số loại biến và cách đặt tên

Loại biến Cách đặt tên biến Ví dụ
Biến cục bộ
[local]
Chữ thường toàn bộ cho các ký tự, ngăn cách mỗi từ trong biến bởi dấu gạch dưới. int age_of_person
char* name
Biến toàn cục
[global]
Chữ thường toàn bộ cho các ký tự, tiền tố g_, ngăn cách mỗi từ trong biến bởi gạch dưới. int g_age_of_person
char* g_name
Biến dạng static Chữ thường toàn bộ cho các ký tự, tiền tố s_, ngăn cách mỗi từ trong biến bởi gạch dưới. int s_age_of_person
char* s_name
Biến dạng hằng
[constant]
Viết hoa toàn bộ các ký tự, tiền tố C_ hoặc k_, ngăn cách mỗi từ trong biến bởi gạch dưới. const int C_AGE_OF_PERSON
const char* C_NAME
Các trường
của struct và class
Chữ thường toàn bộ cho các ký tự, tiền tố m_, ngăn cách mỗi từ trong trường này bởi gạch dưới. int m_age_of_person
char* m_name
Các trường static của struct và class Chữ thường toàn bộ cho các ký tự, tiền tố s_, ngăn cách các từ trong trường bởi gạch dưới. int s_age_of_person
char* s_name

Các quy tắc khác

  • Biến truyền vào hàm sẽ viết thường toàn bộ các ký tự, ngăn cách các từ trong biến bởi dấu gạch dưới.
  • Cách khai báo một struct cần viết hoa các ký tự đầu của mỗi từ tên struct và bắt đầu với tiền tố S, ví dụ struct STesla.
  • Cách khai báo một class cần viết hoa các ký tự đầu của mỗi từ trong tên class và bắt đầu với tiền tố C, ví dụ class CMonster.

Các vấn đề khi khai báo hàm

Với Java, bản thân Java Coding Convention rất chặt chẽ, trong các khai báo hàm của Java sử dụng cách viết thường ký tự đầu tiên của tên hàm: createBasicSinsWithData[], playEffectDestroySins[].

Với Coding Convention có thể học hỏi từ Java Coding Convention hoặc viết hoa chữ cái đầu tiên của các từ trong tên hàm, ta có ví dụ cho cách thứ 2 này: CreateBasicSinsWithData[], PlayEffectDestroySins[].

Cách đặt tên hàm phải mang nghĩa nhất định

Việc đặt tên hàm mang ý nghĩa cũng như đặt tên biến có ý nghĩa như đã trình bày ở trên, đặt tên hàm hay biến càng mang đầy đủ ý nghĩa sẽ càng tốt.

Mức độ 1: xét ví dụ với hàm có ý nghĩa thấp sau, hàm create[...]

LightSins* LightSins::create[eBasicSinsColor color] { LightSins* ret = new LightSins[]; if[ret && ret->init[color]] { ret->autorelease[]; return ret; } SAFE_DEL[ret]; return NULL; }

Mức độ 2: gia tăng ý nghĩa hơn cho hàm create[...], đặt lại tên hàm với nhiều từ hơn, sửa create[...] thành createLightSins[...]

LightSins* LightSins::createLightSins[eBasicSinsColor color] { LightSins* ret = new LightSins[]; if[ret && ret->init[color]] { ret->autorelease[]; return ret; } SAFE_DEL[ret]; return NULL; }

Mức độ 3: làm rõ nghĩa hơn nữa, điều chỉnh thành createLightSinsWithColor[...]

LightSins* LightSins::createLightSinsWithColor[eBasicSinsColor color] { LightSins* ret = new LightSins[]; if[ret && ret->init[color]] { ret->autorelease[]; return ret; } SAFE_DEL[ret]; return NULL; }

Khi sử dụng hàm trên sẽ tránh mất thời gian hơn trong bảo trì xem cần truyền tham số thuộc loại nào vào hàm, đôi lúc không cần xem phần hiện thực cũng có thể đoán được ý nghĩa của hàm.

Các vấn đề khác về soạn thảo văn bản

Level của 1 khối code

Việc đặt level đúng của 1 khối code là rất quan trọng, giúp xác định nhanh hơn "tầm vực" của 1 dòng code và xác định vấn đề nhanh hơn.

Xét ví dụ sau, code không được trình bày đúng level

if[m_fAdd1ScoreTimer == 0.0f] { if[m_iScorePool > 0] { int addScore = [int][m_iScorePool * 0.2f]; if[addScore < 1] addScore = 1; m_iScorePool -= addScore; m_iCurrentScore += addScore; m_fAdd1ScoreTimer = DELAY_ADD_1_SCORE; if[m_iScorePool == 0] { m_pScoreLabel->runAction[ CCSequence::create[ CCScaleTo::create[0.05f, 2.0f*m_ScaleFactorScore], CCScaleTo::create[0.1f, 1.0f*m_ScaleFactorScore], NULL ]]; } } }

Với code như trên, có thể nhầm lẫn m_iCurrentScore += addScore; nằm cùng cấp với dòng if[m_fAdd1ScoreTimer == 0.0f], tức là nó không nằm trong if.

Thay vì vậy, đưa nó vào đúng level của nó:

if[m_fAdd1ScoreTimer == 0.0f] { if[m_iScorePool > 0] { int addScore = [int][m_iScorePool * 0.2f]; if[addScore < 1] addScore = 1; m_iScorePool -= addScore; m_iCurrentScore += addScore; m_fAdd1ScoreTimer = DELAY_ADD_1_SCORE; if[m_iScorePool == 0] { m_pScoreLabel->runAction[CCSequence::create[ CCScaleTo::create[0.05f, 2.0f*m_scaleFactorPts], CCScaleTo::create[0.1f, 1.0f*m_scaleFactorPts], NULL ]]; } } }

Đặt dấu [chấm, phẩy, hai chấm, chấm phẩy, hỏi, chấm than]

Theo phương pháp đặt dấu trong văn bản thì "dấu câu" trong code cũng có vài nét tương đồng. Nguyên tắc là dấu sẽ nằm ngay phía sau ký tự cuối và sau đó là đến khoảng trắng rồi mới đến ký tự kế tiếp.

Ví dụ đặt dấu sai, xem xét khảo sát tại dấu phẩy , và dấu chấm .

  • Twinkle ,twinkle ,little star ,how I wonder what you are. [sai chỗ dấu phẩy, đúng chỗ dấu chấm]
  • Twinkle,twinkle,little star,how I wonder what you are . [sai chỗ dấu phẩy, sai chỗ dấu chấm]
  • Twinkle, twinkle, little star, how I wonder what you are . [đúng chỗ dấu phẩy, sai chỗ dấu chấm]

Cách đặt dấu đúng dựa theo nguyên tắc đã đề cập phía trên:

Twinkle, twinkle, little star, how I wonder what you are.

Từ cách trình bày văn bản như trên, tận dụng vào việc trình bày code, xét ví dụ code về việc đặt dấu sau

playActionFollowDelete[1,this,callfunc_selector[SinsDestroy::playDone]] ;

Các dấu phẩy hay chấm phẩy như trên đặt không tốt, có thể trình bày lại như sau

playActionFollowDelete[1, this, callfunc_selector[SinsDestroy::playDone]];

Cách dòng trong code

Khảo sát đoạn code sau, đây là đoạn code đã cách dòng tốt

void CLoadingData::releaseAllResource[] { m_iNumBackgroundAudios = 0; // RELEASE SPRITE for[u8 i = 0; i < m_tSpritePacks.size[]; i++] { GetSpriteManager[]->unloadSprite[m_tSpritePacks.at[i]]; } m_tSpritePacks.clear[]; // RELEASE AFX for[u8 i = 0; i < m_tAudioPacks.size[]; i++] { unloadEffect[m_tAudioPacks.at[i]]; } m_tAudioPacks.clear[]; }

Xem xét đoạn từ comment // RELEASE SPRITE và tới đoạn // RELEASE AFX, giữa 2 đoạn đó cách nhau bởi 1 dòng trống [blank] [dòng 11]. Ý nghĩa của nó nhằm ngăn cách 2 khối code có 2 chức năng khác nhau, như vậy khi bảo trì có thể nhanh chóng xác định được đoạn code nào làm việc gì thay vì để liên tục từ trên xuống như đoạn code bên dưới.

void CLoadingData::releaseAllResource[] { m_iNumBackgroundAudios = 0; // RELEASE SPRITE for[u8 i = 0; i < m_tSpritePacks.size[]; i++] { GetSpriteManager[]->unloadSprite[m_tSpritePacks.at[i]]; } m_tSpritePacks.clear[]; // RELEASE AFX for[u8 i = 0; i < m_tAudioPacks.size[]; i++] { unloadEffect[m_tAudioPacks.at[i]]; } m_tAudioPacks.clear[]; }

Từ đây, bạn có thể tự thiết kế nên chuẩn mực chung của nhóm làm việc, hoặc học cách tuân theo chuẩn mực cho các dự án sau này.

Bài chung series

Viết Code là một hoạt động không thể tránh khỏi khi bạn trở thành một lập trình viên. Tuy nhiên, để viết “Code sạch, Code đẹp” sao cho cả đội nhóm cùng hiểu là một vấn đề không thể thực hiện trong “một sớm một chiều”. Vì thế, Code Convention là một điều cần thiết để giúp Code của bạn tốt hơn. Vậy, Code Convention là gì? Những quy tắc chung khi viết Code ra sao?

Code Convention được tạm dịch là quy ước viết Code. Có thể hiểu một cách đơn giản, Code Convention là một tập hợp các quy ước về cách để viết Code, đặt tên biến, class, hàm, file và rất nhiều quy tắc khác như thụt đầu dòng, comment, cách “.” cách “,”,… để cho các khối Code trở nên “clean” hơn.

Trong một dự án phần mềm lớn, khi toàn bộ lập trình viên của dự án đều tuân theo một quy tắc viết Code, giúp việc giao tiếp giữa các thành viên trở nên dễ dàng hơn. Dự án cũng sẽ có thể thêm các module chức năng nhanh chóng hơn, việc bảo trì và phát triển hệ thống sau này cũng sẽ dễ dàng hơn.

Khi Code có Convention, hay Code theo quy tắc chung mà mọi người đều biết, điều này sẽ giúp cho hoạt động làm việc theo nhóm trở nên dễ dàng hơn. Trừ một số trường hợp đặc biệt, thông thường, một dự án phần mềm không thể được hoàn thiện chỉ với một cá nhân mà sẽ được thực hiện theo nhóm. Nếu mỗi người viết một phong cách khác nhau, những người còn lại sẽ “gai mắt” hoặc không hiểu bạn đang viết gì.

Vì thế, việc Code theo một quy ước chung sẽ giúp cho cả nhóm làm việc trơn tru hơn, hiểu nhau hơn và giảm thiểu tình trạng những câu hỏi như: “Bạn viết cái gì vậy!” “Cái này là cái gì vậy bạn hiền?”,…

Vậy, khi Code Convention chúng ta sẽ có những lợi ích như sau:

  • Giúp làm việc nhóm hiệu quả hơn
  • Thống nhất và tuân thủ theo một chuẩn dễ dàng làm việc hơn
  • Giúp người khác nắm bắt Code bạn viết nhanh hơn
  • Dễ dàng nâng cấp và cải tiến phần mềm
  • Có thể tái sử dụng trong nhiều phần mềm khác nhau
  • Thuận lợi trong việc phát triển và bảo trì hệ thống sau này

Tổng hợp những quy tắc chung khi viết Code

Naming Convention – quy tắc đặt tên

Một trong những việc khiến người khác có thể hiểu Code của bạn viết gì là thông qua: cách đặt tên các biến, hằng, class,… có thể gọi chung là định danh.

Khi thực hiện một bài tập nhỏ lúc bạn học tin học cấp 3 hay những bài tập giải thuật đơn giản, chúng ta được chỉ cách đặt tên biến là a, b, c, d. Tuy nhiên, điều này chỉ áp dụng cho những bài tập cấp thấp và không có quá nhiều chức năng.

Hãy tưởng tượng, một phần mềm khổng lồ như Windows với cả ngàn chức năng, liệu việc đặt tên a-b-c-d sẽ hiệu quả trong việc phát triển? Không hề! Nếu bạn đang học đại học/cao đẳng/ trung cấp và các thầy cô dạy vẫn chưa nói gì về đặt tên các hàm, các biến, sớm thôi họ cũng sẽ nhắc nhở bạn đấy!

Chúng ta sẽ có các cách đặt tên phổ biến như sau:

ADVERTISEMENT

  • Cú pháp lạc đà – camelCase
  • Cú pháp Pascal – PascalCase
  • Cú pháp con rắn – snake_case

Tùy theo ngôn ngữ sẽ có một cách để sử dụng cú pháp riêng, nhưng bạn có thể tham khảo những ví dụ sẽ được nêu ngay sau đây nhé!

Trong hầu hết các công ty phần mềm trong nước hay ngoài nước, quy tắc đặt định danh đều sẽ được mặc định là sử dụng tiếng Anh.

Cú pháp lạc đà là cú pháp có cách viết từ đầu tiên của cụm sẽ là viết thường và ký tự của những từ tiếp theo sẽ được viết hoa.

Thông thường, cú pháp này sẽ được dùng để viết các hàm, tên biến, phương thức.

Ví dụ về phương thức, hàm: firstName, lastName, runLow[], getOnTop[],…

Ví dụ về biến: int i; float spaceX,…

Cú pháp Pascal – PascalCase

Cú pháp Pascal là cú pháp sẽ được viết theo dạng viết hoa tất cả các ký tự đầu tiên trong từ của cụm.

Bạn có thể thấy việc này quá quen thuộc khi học Pascal lúc cấp 3, khi gõ lại bài tập từ một “thanh niên” nào đó “cứu” cả lớp đúng chứ? Thông thường, cú pháp này được sử dụng cho tên class, đôi khi là cả tên biến.

Ví dụ: class Mice, class MickeyMouse,…

Cú pháp con rắn – snake_case

Cú pháp con rắn sẽ có cách viết phổ biến là toàn bộ chữ cái đều viết thường và tách nhau ra bằng dấu gạch dưới “_”. Trong một vài trường hợp, một vài ngôn ngữ, chúng ta có biến thể là viết toàn bộ các chữ cái đều in hoa.

Thông thường, chúng ta sẽ nhìn thấy cú pháp này trong việc đặt tên hằng và đôi khi là tên chương trình.

Ví dụ như: MAX_SLECT, final_final1_final2,…

Ngoài ra, trong lúc đặt tên chúng ta còn cần phải lưu ý thêm:

  • Tên class, tên biến thường sử dụng danh từ
  • Tên hàm sẽ thường bắt đầu bằng động từ
  • Nên đặt tên theo kiểu gợi nhớ đến chức năng của chúng
  • Bạn không nên đặt tên theo kiểu viết tắt. Trong tương lai khi đọc lại Code bạn sẽ không hiểu hiện tại bạn đang viết gì
  • Tránh đặt tên theo kiểu chung chung không có ý nghĩa

Quy tắc số lượng

Một số quy tắc về số lượng trong cuốn sách Clean Code A Handbook of Agile Software Craftsmanship của Robert C. Martin, quyển Refactoring in Large Software Projects: Performing Complex Restructurings Successfully của Martin Lippert cũng như bộ quy tắc của Oracle có ghi như sau:

  • Một dòng Code không nên dài quá 80 ký tự
  • Một câu lệnh nên lồng tối đa 4 cấp
  • Một hàm không nên chứa quá 5 tham số
  • Một hàm không nên quá 30 dòng
  • Một class không nên vượt 500 dòng

Quy tắc comment – bình luận

  • Bạn nên tránh sử dụng comment để giải thích Code, việc hoàn thiện đoạn Code bằng như quy tắc đặt tên sẽ giúp Code của bạn dễ hiểu hơn.
  • Nếu bạn là người mới hoặc mau quên, việc sử dụng comment để giải thích việc mình làm với đoạn Code cũng là một ý hay đấy!

Quy tắc xuống hàng

Theo bộ quy tắc của Oracle, chúng ta có:

  • Nếu một hàm có nhiều cấp lồng nhau, mỗi cấp chúng ta nên xuống dòng.
  • Các đoạn Code bằng cấp nên ở cùng một cột với nhau, dòng xuống hàng nên bắt đầu cùng cấp với dòng phía trên.
  • Xuống hàng trước các toán tử ví dụ như: +, -, *, ?,…

Đến đây, Tino Group đã giải thích cho bạn về “Code Convention là gì” rồi đấy! Bộ quy tắc viết Code sẽ phụ thuộc vào từng ngôn ngữ, từng doanh nghiệp và đôi khi là từng dự án. Vì thế, bạn nên hỏi những người có liên quan trong dự án để nắm về quy tắc gõ để làm việc tốt hơn nhé! Tino Group chúc bạn thành công!

Bài viết có tham khảo từ nhiều nguồn: Viblo, TopDev,…

Những câu hỏi thường gặp về Code Convention

Được. Nếu bạn viết Code đúng nhưng không theo một quy tắc thụt đầu dòng, đặt tên hay khoảng cách nào, chương trình vẫn có thể chạy được. Tuy nhiên, chính bản thân bạn sẽ gặp rắc rối trong tương lai khi bạn không còn nhớ bạn đã viết gì đấy!

Nếu bạn muốn tìm hiểu thêm về các quy tắc viết Code, bạn có thể sử dụng từ khóa: Code Convention hoặc coding Convention để tìm kiếm trên Google hoặc Bing [sẽ cho ra nhiều kết quả tiếng Anh hơn hoặc bạn có thể sử dụng Google kết hợp với bộ lọc]. Nếu muốn, bạn có thể tìm hiểu thêm tại bài viết của University Corporation for Atmospheric Research.

Nếu bạn đang muốn tìm hiểu thêm về quy tắc viết Code chung của JavaScript, bài viết và bài tập về JavaScript Coding Conventions của W3Schools sẽ là một trang rát phù hợp để bạn có thể học tập và nghiên cứu đấy!

Clean Code sẽ giúp cho bạn và đội nhóm khi làm việc trong một dự án phần mềm được trơn tru hơn, bạn cũng có thể tái sử dụng Code của mình cho nhiều dự án khác, cùng nhiều lợi ích khác, Nếu bạn đang muốn tìm hiểu thêm về clean Code, bài viết này của Tino Group sẽ hỗ trợ bạn một phần đấy!

CÔNG TY CỔ PHẦN TẬP ĐOÀN TINO

  • Trụ sở chính: L17-11, Tầng 17, Tòa nhà Vincom Center, Số 72 Lê Thánh Tôn, Phường Bến Nghé, Quận 1, Thành phố Hồ Chí Minh
    Văn phòng đại diện: 42 Trần Phú, Phường 4, Quận 5, Thành phố Hồ Chí Minh
  • Điện thoại: 0364 333 333
    Tổng đài miễn phí: 1800 6734
  • Email:
  • Website: www.tino.org

Video liên quan

Chủ Đề