coding convention

37
STH VIETNAM Java Coding Convention Phiên bản 1.2 1

Upload: vu-thanh-binh

Post on 08-Jul-2016

222 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Coding Convention

STH VIETNAM

Java Coding Convention

Phiên bản 1.2

1

Page 2: Coding Convention

STH VIETNAM

Revision History

Date Version Description Author

2

Page 3: Coding Convention

STH VIETNAM

MỤC LỤC

MỤC LỤC..................................................................................................................3

1 GIỚI THIỆU........................................................................................51.1 Mục đích......................................................................................................51.2 Phạm vi ứng dụng.......................................................................................51.3 Các tài liệu liên quan...................................................................................51.4 Định nghĩa...................................................................................................5

2 CÁC QUY TẮC CHUNG.........................................................................62.1 Đơn giản - Chính xác..................................................................................62.2 Sự vi phạm các quy tắc chuẩn....................................................................6

3 CẤU TRÚC CHƯƠNG TRÌNH.................................................................73.1 Phần mở rộng file........................................................................................73.2 Các file thường sử dụng..............................................................................7

4 TỔ CHỨC FILE....................................................................................84.1 File mã nguồn Java......................................................................................8

5 INDENTATION AND BRACES..............................................................105.1 Tab và Indent............................................................................................105.2 Dấu ngoặc nhọn........................................................................................105.3 Độ dài dòng lệnh.......................................................................................105.4 Ngắt dòng.................................................................................................10

6 CHÚ THÍCH (COMMENTS)..................................................................126.1 Định dạng của Implementation Comment.................................................126.2 Documentation Comments........................................................................14

7 DECLARATIONS................................................................................167.1 Số lượng khai báo trên một dòng..............................................................167.2 Khai báo kiểu mảng (Array Declaration)....................................................167.3 Khởi tạo (Initialization)..............................................................................167.4 Nơi đặtkhai báo (Placement).....................................................................167.5 Khai báo Class và Interface (Class and Interface Declarations).................17

8 CÁC CÂU LỆNH (STATEMENTS)..........................................................188.1 Các câu lệnh đơn giản (Simple Statements)..............................................188.2 Các câu lệnh phức (Compound Statements).............................................188.3 Câu lệnh trả về (Return Statements).........................................................188.4 Các câu lệnh if, if-else, if else-if else.........................................................188.5 Câu lệnh for...............................................................................................198.6 Câu lệnh While..........................................................................................198.7 Câu lệnh Do-while.....................................................................................19

3

Page 4: Coding Convention

STH VIETNAM

8.8 Câu lệnh Switch.........................................................................................208.9 Câu lệnh Try-catch....................................................................................20

9 KHOẢNG TRẮNG (WHITE SPACE).......................................................219.1 Dòng trống (Blank Lines)...........................................................................219.2 Ký tự trống................................................................................................21

10 QUY ƯỚC ĐẶT TÊN (NAMING CONVENTIONS).....................................2210.1 Một số quy ước chung (General Rules)......................................................2210.2 Class/Interface..........................................................................................2210.3 Biến số (Variables)....................................................................................2310.4 Hằng số(Constants)...................................................................................2310.5 Phương thức (Methods).............................................................................23

11 PROGRAMMING PRACTICES..............................................................2511.1 Providing Access to Instance and Class Variables.....................................2511.2 Tham chiếu đến Class Variables và Methods.............................................2511.3 Hằng số (Constants)..................................................................................2511.4 Phép gán (Variable Assignments)..............................................................2511.5 Loggings....................................................................................................2611.6 Performance Practices...............................................................................2611.7 Miscellaneous Practices.............................................................................26

12 CODE EXAMPLES..............................................................................2812.1 Một ví dụ Java Source File.........................................................................28

4

Page 5: Coding Convention

STH VIETNAM

1 GIỚI THIỆU

1.1 Mục đích

Các quy ước về viết code đóng vai trò quan trọng đối với lập trình viên vì những lý do sau :

80% chi phí cho vòng đời của một phần mềm là dành cho việc bảo trì

Hầu như bất cứ phần mềm nào cũng được bảo trì toàn bộ bởi người viết phần mềm đó.

Quy ước về viết code cải thiện tính dễ đọc của phần mềm, cho phép lập trình viên có thể hiểu code mới một cách nhanh chóng và hoàn thiện.

Nếu mã nguồn của bạn đóng vai trò là một sản phẩm, bạn cần đảm bảo nó được đóng gói một cách hoàn thiện và rõ ràng như bất cứ một sản phẩm phần mềm nào khác.

1.2 Phạm vi ứng dụng

1.3 Các tài liệu liên quan

No. Code Tên tài liệu

1 SUN Java Coding Conventions

Java Language Specification – Sun Microsystems, Inc.http://java.sun.com/docs/codeconv/

1.4 Định nghĩa

Khái niệm Giải thích

5

Page 6: Coding Convention

STH VIETNAM

2 CÁC QUY TẮC CHUNG

2.1 Đơn giản - Chính xác

Code phải đơn giản và dễ hiểu

Code phải chính xác và chắc chắnCần có một quy tắc chung về khoảng cách, indent, tên, access modifiers …

Không nên tối ưu hóa code một cách vội vàngTrừ khi bạn thực hiện xuất nhập dữ liệu hoặc thực hiện hàng triệu lần với cùng một thao tác, không nên tối ưu hóa code một cách vội vàng.

2.2 Sự vi phạm các quy tắc chuẩn

Không có tiêu chuẩn nào là hoàn hảo và cũng không có tiêu chuẩn nào có thể áp dụng được trong mọi trường hợp: có thể bạn sẽ gặp trường hợp không thể áp dụng một hoặc nhiều tiêu chuẩn nào đó.

Bất cứ sự vi phạm tiêu chuẩn nào cải thiện tính dễ đọc thì đều có thể được chấp nhận

Mục tiêu chính của tài liệu là cải thiện tính dễ đọc do đó tăng khả năng hiểu, duy trì và chất lượng chung của code. Tuy nhiên bạn cũng nên hiểu rằng nó không thể bạo quát hết các trường hợp cụ thể.

Khi bạn vi phạm tiêu chuẩn, hãy ghi lại những thay đổi nàyTất cả các tiêu chuẩn đều có thể bị thay đổi. Nếu bạn làm vậy, bạn cần ghi lại lí do bạn thay đổi tiêu chuẩn, các điều kiện có thể/ phải xảy ra trước khi tiêu chuẩn có thể áp dụng vào trường hợp này. Cuối cùng, bạn cần hiểu mỗi tiêu chuẩn, hiểu được khi nào thì áp dụng chúng cũng như trường hợp không thể áp dụng.

Các dự án có thể điều chỉnh lại tài liệu này cho riêng dự ánDựa trên yêu cầu của khách hàng, các dự án có thể sử dụng tiêu chuẩn code được cung cấp bởi khách hàng hoặc điều chỉnh lại tài liệu chuẩn này cho phù hợp với yêu cầu riêng của khách hàng.

6

Page 7: Coding Convention

STH VIETNAM

3 CẤU TRÚC CHƯƠNG TRÌNHPhần này sẽ liệt kê các phần mở rộng và tên file thường sử dụng.

3.1 Phần mở rộng file

Phần mềm viết bằng ngôn ngữ Java sử dụng các phần mở rộng file sau :

Kiểu file Phần mở rộng

Mã nguồn Java .java

Mã nhị phân Java .class

3.2 Các file thường sử dụng

Các file thường sử dụng bao gồm :

Tên file Mục đích

README File tổng kết nội dung của một thư mục

7

Page 8: Coding Convention

STH VIETNAM

4 TỔ CHỨC FILEMột file bao gồm nhiều phần, các phần này nên được tách biệt nhau bởi các dòng trống và các chú thích không bắt buộc để xác định mỗi phần.

File có độ dài hơn 2000 dòng hoặc có nhiều hơn 50 phương thức sẽ rất nặng nề và nên tránh. Ví dụ về một chương trình Java mẫu, viết đúng định dạng xem trong phần "Ví dụ file mã nguồn Java" trong trang 19.

4.1 File mã nguồn Java

Mỗi file mã nguồn Java chứa một public class đơn hoặc một interface. Nếu các private class và interface được kết hợp với một public class, bạn có thể đặt chúng trong cùng file mã nguồn dưới dạng một public class. Public class nên là class hoặc interface đầu tiên trong file.

File mã nguồn Java có thứ tự như sau :

Các chú thích ban đầu (xem "Beginning Comments" trong trang 4)

Các câu lệnh pakage và import.

Các khai báo class và interface (xem "Khai báo Class và Interface" trong trang 4)

4.1.1 Chú thích ban đầuTất cả các file mã nguồn của một dự án nên có chung định dạng của chú thích ban đầu, chứa các thông tin như tên class, thông tin phiên bản, thời gian, ghi chú về copyright, các log về sự thay đổi mã nguồn …

Đây là một ví dụ mẫu về định dạng chú thích ban đầu:

/* * Copyright (C) 2005 by SthVietnam Software Company * * $Id: Blah.java,v 1.1 2006/01/11 03:43:05 quangtn Exp $ * */

4.1.2 Các câu lệnh Pakage và ImportCâu lệnh pakage là câu lệnh đầu tiên mà không phải là chú thích của hầu hết các file mã nguồn Java. Trong công ty SthVietnam, tất cả các pakage Java luôn được bắt đầu bằng net.SthVietnam, trừ trường hợp được quy định bởi khách hàng.

Tiếp theo sẽ là các câu lệnh import. Ví dụ:

package net.SthVietnam.util;

8

Page 9: Coding Convention

STH VIETNAM

import java.awt.peer.CanvasPeer;

Ghi chú: phần tử đầu tiên của một package luôn viết bằng kí tự ASCII thường và nên là một trong các tên miền top-level, hiện tại làc các tên miền com, edu, gov, mil, net, org hoặc một trong các mã 2 ký tự bằng tiếng Anh để xác định tên quốc gia (quy định trong chuẩn 3166 của ISO).4.1.3 Khai báo Class và InterfaceBảng dưới đây mô tả các thành phần của một khai báo class hoặc interface theo đúng thứ tự mà nó sẽ xuất hiện. Xem ví dụ "Java Source File Example" trong trang 19.

No Phần khai báo của Class/Interface Ghi chú

1Chú thích tài liệu Class/interface (/**...*/)

Xem chi tiết "Chú thích tài liệu" trong trang 9

2 Câu lệnh class or interface

3Chú thích cài đặt Class/interface (nếu cần thiết) (/*...*/)

Phần chú thích này chứa các thông tin về class hoặc interface mà không thuộc vào phần chú thích tài liệu.

4 Các hằng số (static final)Đầu tiên là các hằng số public, sau đó đến protected, tiếp theo là hằng số mức package (không có access modifier), và cuối cùng là private.

5 Các biến của Class (static) Đầu tiên là các biến public, sau đó đến protected, tiếp theo là hằng số mức package (không có access modifier), và cuối cùng là private.

6 Các biến của instanceĐầu tiên là các biến public, sau đó đến protected, tiếp theo là hằng số mức package (không có access modifier), và cuối cùng là private.

7 Constructors

8 Các phương thức

Các phương thức này nên được nhóm theo chức năng, chứ không nên nhóm theo phạm vi hoặc khả năng truy nhập. Ví dụ, một phương thức của lớp có kiểu private có thể nằm giữa 2 phương thức của instance kiểu public. Mục đích là làm cho việc đọc hiểu code dễ dàng hơn.

9 Inner classes/interfaces

9

Page 10: Coding Convention

STH VIETNAM

5 INDENTATION AND BRACES

5.1 Tab và Indent

Một đơn vị của indent được tính bằng 4 kí tự trống.Không nên sử dụng kí tự tab vì các trình biên soạn khác nhau thì kí tự này lại khác nhau.Indent tiếp theo sẽ là 8 kí tự trống ( bằng 2 mức indent thường).

5.2 Dấu ngoặc nhọn

Dấu ngoặc nhọn mở “{“ của khai báo class/ method và các khối lệnh khác nên đặt tại cuối của dòng lệnh đầu tiên trong khối lệnh đó.

5.3 Độ dài dòng lệnh

Tránh viết dòng lệnh dài hơn 80 hoặc 120 kí tự vì một số tool sẽ không xử lý tốt được những dòng lệnh này.Ghi chú: Các đoạn code trong các tài liệu nên có độ dài ngắn hơn bình thương, nhỏ hơn 70 kí tự.

5.4 Ngắt dòng

Khi một biểu thức dài hơn một dòng đơn, cần ngắt chúng theo nguyên tắc sau :

Ngắt sau dấu phẩy

Ngắt sau toán tử logic

Ngắt trước toán tử

Những quy ước ngắt có độ ưu tiên cao hơn sẽ được ưu tiên trước.

Căn dòng mới được ngắt cùng cấp với dòng trước nó.

Nếu quy tắc trên dẫn đến sự nhầm lẫn code hoặc code vượt quá lề phải thì sử dụng indent với 8 kí tự trống để thay thế

Dưới đây là một số ví dụ ngắt các lời gọi phương thức:

someMethod(longExpression1, longExpression2, longExpression3, longExpression4, longExpression5); var = someMethod1(longExpression1, someMethod2(longExpression2, longExpression3));

Dưới đây là 2 ví dụ ngắt dòng cho các biểu thức số học. Ví dụ đầu iên được ưu tiên sử dụng do vị trí ngắt nằm bên ngoài biểu thức trong ngoặc đơn (là biểu thức có độ ưu tiên cao hơn).

longName1 = longName2 * (longName3 + longName4 - longName5) + 4 * longname6; // NÊN SỬ DỤNG

10

Page 11: Coding Convention

STH VIETNAM

longName1 = longName2 * (longName3 + longName4 - longName5) + 4 * longname6; // NÊN TRÁNH

Dưới đây là 2 ví dụ khi sử dụng indent trong khai báo phương thức. Đầu tiên là trường hợp theo quy ước. Trường hợp 2, nếu sử dụng indent theo quy ước sẽ làm cho dòng thứ 2 và thứ 3 kéo dài về bên phải, do đó sử dụng ident bằng 8 dấu cách.

//INDENT THEO QUY ƯỚCsomeMethod(int anArg, Object anotherArg, String yetAnotherArg, Object andStillAnother) { ...}

//SỬ DỤNG 8 DẤU CÁCH ĐỂ TRÁNH CÁC INDENT DÀIprivate static synchronized horkingLongMethodName(int anArg, Object anotherArg, String yetAnotherArg, Object andStillAnother) { ...}

Ngắt dòng cho biểu thức if nên sử dụng quy tắc 8 dấu cách do việc sử dụng 4 dấu cách làm cho phần body của biểu thức khó theo dõi.

Ví dụ:

//KHÔNG SỬ DỤNG CÁCH INDENT NÀYif ((condition1 && condition2) || (condition3 && condition4) || !(condition5 && condition6)) { //NGẮT SAI doSomethingAboutIt(); //KHIẾN CHO DỄ NHẦM LẪN DÒNG NÀY}

//THAY VÀO ĐÓ SỬ DỤNG CÁCH INDENT SAUif ((condition1 && condition2) || (condition3 && condition4) || !(condition5 && condition6)) { doSomethingAboutIt();} //HOẶC SỬ DỤNGif ((condition1 && condition2) || (condition3 && condition4) || !(condition5 && condition6)) { doSomethingAboutIt();}

Dưới đây là 3 cách để định dạng biểu thức điều kiện rút gọn.

alpha = (aLongBooleanExpression) ? beta : gamma;

alpha = (aLongBooleanExpression) ? beta : gamma;

alpha = (aLongBooleanExpression) ? beta : gamma;

11

Page 12: Coding Convention

STH VIETNAM

6 CHÚ THÍCH (COMMENTS)Trong các chương trình Java ta có thể dùng hai cách chú thích: implementation comments và documentation comments. Implementation comments là những comment có thể thấy trong C++ như /*... */ và //. Documentation comment (hay còn gọi là “doc comment”) là những comment của riêng Java và được giới hạn trong /**...*/. Doc comments có thể được xuất thành các file HTML khi sử dụng javadoc tool.

Implementation comments là các comment dùng cho việc tạm chú thích một đoạn code mà có thể về sau cần dùng đến hoặc để chú thích cho một đoạn implement riêng biệt nào đó. Doc comments dùng để mô tả các tính năng của đoạn mã để sao cho một người lập trình khi không có đoạn source code đó trong tay cũng có thể hiểu được đoạn code đó làm việc gì.

Comment nên được sử dụng để đưa các thông tin chung về code và cung cấp thêm các thông tin mà nếu chỉ đọc code không thì sẽ khó nhận ra. Comment chỉ nên chứa các thông tin liên quan đến việc đọc hiểu chương trình. Ví dụ các thông tin như package này được tạo như thế nào và nó nằm trong directory nào thì không nên đưa vào comment.

Đưa ra các comment cho những đoạn phức tạp, khó hiểu là một việc làm thích hợp, nhưng đối với những đoạn code được coi là “dễ hiểu”, bản thân nó đã chỉ rõ ra nó đang làm gì thì không nên comment nó nữa.

Chú ý: Quá nhiều comment sẽ làm giảm chất lượng code. Do đó, khi bạn cảm thấy buộc phải viết comment thì hãy nên suy nghĩ xem liệu mình có thể làm cho đoạn code đó trở nên dễ đọc hơn không.Comment không nên để trong một khung lớn được bao bằng các ký tự đặc biệt hay các ký tự khác. Comment không nên chứa các ký tự đặc biệt như form-feed và backspace.

6.1 Định dạng của Implementation Comment

Chương trình có thể có 4 loại implementation comments: theo khối (block), dòng đơn (single-line), comment theo code (trailing) và comment cuối dòng (end-of-line).6.1.1 Block Comments Các block comment được dùng để mô tả files, phương thức (methods), cấu trúc dữ liệu và thuật toán. Block comments có thể được sử dụng ở đầu của mỗi file và trước mỗi một method. Nó còn có thể được sử dụng ở các chỗ khác như ở bên trong các method. Các block comment khi ở bên trong method hoặc function thì phải được viết lùi vào bằng với mức của các code mà nó muốn chú thích.Một block comment thì trước nó phải được đặt một dòng trống để phân cách nó với phần còn lại của code, khỏi bị lẫn.

/*

12

Page 13: Coding Convention

STH VIETNAM

* Đây là một block comment. */

Block comment bắt đầu bằng /*-, được xác định bởi indent(1), là phần đầu của block comment và không nên định dạng lại. Ví dụ:

/*-* Here is a block comment with some very special * formatting that I want indent(1) to ignore. * * one * two * three */

Chú ý: Nếu bạn không sử dụng indent(1), bạn không cần phải sử dụng /*- trong code của bạn hoặc làm một concessions nào đó mà có lẽ một ai đó có thể run indent(1) trên code của bạn. Xem thêm "Documentation Comments" ở trang 9.

6.1.2 Single-Line CommentsCác comment ngắn có thể xuất hiện trên một dòng cùng mức với đoạn code theo sau nó. Nếu một comment không thể viết trên một dòng được, thì nên đặt nó trong block comment (Xem phần 6.1.1). Phía trước một single-line comment nên đặt một dòng trống. Đây là một ví dụ của một single-line comment trong Java (xem thêm "Documentation Comments" ở trang 9):

if (condition) { // Handle the condition. ...}

6.1.3 Trailing CommentsCác comment “rất ngắn” có thể xuất hiện trên cùng một dòng với code mà nó muốn mô tả, nhưng nó phải được đẩy ra đủ xa để có thể phân biệt nó với phần câu lệnh. Nếu trong một đoạn code có nhiều hơn 1 short comment thì tất cả nên được viết thụt vào cùng mức với nhau.Dưới đây là một ví dụ của trailing comment trong Java:

if (a == 2) { return TRUE; // special case} else { return isPrime(a); // works only for odd a}

6.1.4 End-Of-Line CommentsComment // có thể comment out toàn bộ một dòng hoặc một phần của dòng đó. Không nên sử dụng nó một cách liên tục để comment các đoạn text; tuy nhiên, nó có thể được

13

Page 14: Coding Convention

STH VIETNAM

dùng liên tục để comment out một đoạn code. Ví dụ sau đây là 3 kiểu comment sử dụng end-of-line comment:

if (foo > 1) {

// Do a double-flip. ...} else { return false; // Explain why here.}//if (bar > 1) {// // Do a triple-flip.// ...//} else { // return false;//}

6.2 Documentation Comments

Chú ý: Xem các ví dụ về các định dạng comment được mô tả tại đây ở phần "Java Source File Example" - trang 19 Để biết thêm chi tiết, bạn có thể đọc "How to Write Doc Comments for Javadoc" bao gồm cả các thông tin khác cho các tag của doc comment như (@return, @param, @see): http://java.sun.com/products/jdk/javadoc/writingdoccomments.html

Các thông tin thêm về doc comments và javadoc, xin mời ghé qua trang chủ của javadoc tại : http://java.sun.com/products/jdk/javadoc/

Doc comment mô tả các Java class, interfaces, constructors, methods, và fields. Mỗi doc comment được đặt trong /**...*/, và với mỗi class, interface, hoặc member đều có một doc comment. Comment này nên được đặt ngay phía trước phần khai báo:

/** * The Example class provides ... */public class Example { ...

Chú ý là các top-level classes và các interfaces thì không bị viết thụt vào, còn các member của nó thì phải viết thụt vào. Dòng đầu tiên của doc comment (/**) cho các classes và interfaces không viết thụt; các dòng tiếp theo của doc comment được viết thụt vào một khoảng trắng, thẳng hàng với * ở phía trên. Đối với các members, kể cả các constructors thì có 4 khoảng trắng ở dòng đầu của doc comment và các dòng sau thì là 5 khoảng trắng.

Nếu bạn cần đưa thông tin về class, interface, variable, hoặc method mà nó không thích hợp với việc tạo documentation thì sử dụng implementation block comment (xem phần 6.1.1) hoặc single-line (xem phần 6.1.2) comment ngay phía sau phần khởi tạo. Ví dụ,

14

Page 15: Coding Convention

STH VIETNAM

chi tiết về việc implementation một class nên được đặt trong một implementation block comment đặt sau class statement, không nên đặt trong phần class doc comment. Doc comments không nên đặt trong phần định nghĩa method hoặc constructor, vì Java liên kết documentation comments với phần khai báo ngay sau comment đó.

15

Page 16: Coding Convention

STH VIETNAM

7 DECLARATIONS

7.1 Số lượng khai báo trên một dòng

Nên sử dụng mỗi khai báo trên một dòng vì nó thuận tiện cho việc ghi comment. Hay nói cách khác, nên sử dụng kiểu:,

int level; // indentation levelint size; // size of table

hơn là cách khai báo

int level, size;

Không nên khai báo các biến với các kiểu khác nhau trên cùng một dòng, ví dụ:

int foo, fooarray[]; //SAI!

Chú ý: Các ví dụ trên sử dụng một space giữa kiểu và biến. Một cách khác là sử dụng tab, ví dụ:

int level; // indentation levelint size; // size of tableObject currentEntry; // currently selected table entry

7.2 Khai báo kiểu mảng (Array Declaration)

Mặc dù Java hỗ trợ 2 cách khai báo kiểu mảng, nhưng chúng ta nên chỉ đi theo một kiểu khai báo như sau:

int anIntArray[]; // Không nênint[] anIntArray; // Nên theo cách này

7.3 Khởi tạo (Initialization)

Nên khởi tạo các biến cục bộ ngay khi chúng được khai báo. Chỉ có một lý do duy nhất để không nên khởi tạo chúng ngay khi khai báo là khi giá trị khởi tạo của nó phải phụ thuộc vào một tính toán nào đó trước.

7.4 Nơi đặt khai báo (Placement)

Chỉ đặt các khai báo ở phần đầu của các block. (Một block là một đoạn code nào đó được bao quanh bởi cặp dấu “{“ và “}”.). Không nên đợi đến khi nào cần sử dụng rồi mới khai báo nó; nó có thể gây ra sự rối rắm cho các programmer không cẩn thận khác và giảm tính portable của đoạn code đó.

void myMethod() { int int1 = 0; // phần đầu của method block

if (condition) { int int2 = 0; // phần đầu của "if" block ...

16

Page 17: Coding Convention

STH VIETNAM

}}

Có một ngoại lệ đó là chỉ số của các vòng lặp for, đó là ta có thể khai báo nó trong câu lệnh for:

String tempString;for (int i = 0; i < maxLoops; i++) { tempString = ...; ... }

Các biến cục bộ được sử dụng trong vòng lặp nên được khai báo ở bên ngoài và ngay trước câu lệnh lặp (giống như ví dụ trên).Tránh các khai báo mà nó có thể làm ẩn đi các khai báo đã có ở mức cao hơn. Ví dụ, không nên khai báo một biến cùng tên ở một block phía trong:

int count;...myMethod() { if (condition) { int count = 0; // AVOID! ... } ...}

7.5 Khai báo Class và Interface (Class and Interface Declarations)

Khi viết các Java class và interface, cần phải tuân theo những điều sau:

Dấu mở "{" phải được đặt ở cuối dòng.

Dấu đóng "}" phải được đặt ở một dòng mới.

class Sample extends Object { int ivar1; int ivar2;

Sample(int i, int j) { ivar1 = i; ivar2 = j; }

int emptyMethod() { ... }

...}

Các method phải được cách nhau bằng một dòng trống

17

Page 18: Coding Convention

STH VIETNAM

8 CÁC CÂU LỆNH (STATEMENTS)

8.1 Các câu lệnh đơn giản (Simple Statements)

Mỗi dòng chỉ nên chứa nhiều nhất là một câu lệnh. Ví dụ:

argv++; // Đúngargc--; // Đúng argv++; argc--; // KHÔNG NÊN!

8.2 Các câu lệnh phức (Compound Statements)

Các câu lệnh phức là các câu lệnh chứa danh sách các câu lệnh được đặt trong cặp dấu "{ statements }". Xem ví dụ ở các phần sau.

Các câu lệnh được bao ở phía trong phải được viết lùi vào một mức (so với câu lệnh phức).

Dấu mở “{” phải được đặt ở cuối dòng đầu tiên của câu lệnh phức; dấu đóng “}” phải được đặt ở đầu dòng và được viết lùi sao cho cùng mức với câu lệnh đầu tiên của câu lệnh phức.

Các dấu đóng và mở được dùng để bao tất cả các câu lệnh (kể các các câu lệnh đơn) khi nó là một phần của cấu trúc điều khiển, ví dụ như các câu lệnh if-else hay for. Điều này giúp ta khi thêm các câu lệnh vào thì cũng không gây ra các bug chỉ vì quên thêm các dấu dóng và mở.

8.3 Câu lệnh trả về (Return Statements)

Một câu lệnh return không nên sử dụng ngoặc đơn trừ khi nó làm cho giá trị trả về được rõ ràng hơn bằng một cách nào đó. Ví dụ:

return;

return myDisk.size();

return (size ? size : defaultSize);

8.4 Các câu lệnh if, if-else, if else-if else

Các câu lệnh if-else nên theo các định dạng sau:

if (condition) { statements;}

if (condition) { statements;} else { statements;

18

Page 19: Coding Convention

STH VIETNAM

}

if (condition) { statements;} else if (condition) { statements;} else { statements;}

Chú ý: Câu lệnh if luôn sử dụng cặp dấu {}. Tránh sử dụng kiểu viết như sau – dễ gây ra lỗi khi ta thêm các câu lệnh khác:

if (condition) //AVOID! THIS OMITS THE BRACES {}! statement;

8.5 Câu lệnh for

Một câu lệnh for nên viết theo định dạng sau:

for (initialization; condition; update) { statements;}

Một câu lệnh for rỗng (tức là công việc của nó chỉ cần khởi tạo, điều kiện, và câu lệnh update) thì nên viết theo định dạng sau:

for (initialization; condition; update);Khi sử dụng toán tử comma trong câu lệnh khởi tạo hoặc update của câu lệnh for, phải chú ý tránh sự phức tạp của việc sử dụng nhiều hơn 3 biến. Nếu thực sự cần thiết thì hãy sử dụng các câu lệnh riêng biệt trước vòng lặp for (với các câu lệnh khởi tạo) hoặc là sau vòng lặp for (với các câu lệnh update).

8.6 Câu lệnh While

Một câu lệnh while nên theo định dạng sau:

while (condition) { statements;}

Một câu lệnh while rỗng nên theo định dạng sau:

while (condition);

8.7 Câu lệnh Do-while

Một câu lệnh do-while nên theo định dạng sau:

do { statements;} while (condition);

19

Page 20: Coding Convention

STH VIETNAM

8.8 Câu lệnh Switch

Một câu lệnh switch nên viết theo định dạng sau:

switch (condition) {case ABC: statements; /* falls through */

case DEF: statements; break;

case XYZ: statements; break;

default: statements; break;}

Mọi câu lệnh switch nên có trường hợp default. Câu lệnh break ở trường hợp default có thể bị coi là rườm ra, nhưng nó giúp cho việc tránh các lỗi tiềm tàng về sau nếu ta thêm các case ở sau nó.

8.9 Câu lệnh Try-catch

Một câu lệnh try-catch nên có định dạng như sau:

try { statements;} catch (ExceptionClass e) { statements;}

Một câu lệnh try-catch nên có cả finally, nơi mà chắc chắn sẽ được thực hiện không cần biết là try block có được chạy thành công hay không.

try { statements;} catch (ExceptionClass e) { statements;} finally { statements;}

20

Page 21: Coding Convention

STH VIETNAM

9 KHOẢNG TRẮNG (WHITE SPACE)

9.1 Dòng trống (Blank Lines)

Các dòng trống giúp ta dễ đọc vì phân tách các những đoạn code có liên hệ với nhau. Nên sử dụng 2 dòng trống trong các trường hợp sau:

Giữa các phần của một soure code file.

Giữa các phần định nghĩa class và interface.

Nên sử dụng một dòng trống trong các trường hợp sau:

Giữa các method

Giữa các biến cục bộ trong một method và câu lệnh đầu tiên của nó.

Trước một block (xem phần 6.1.1) hoặc một single-line comment (xem phần 6.1.2)

Giữa các phần liên quan với nhau bên trong một method để tăng tính dễ đọc.

9.2 Ký tự trống

Nên sử dụng các ký tự trống trong các trường hợp sau:

Một keyword theo sau dấu ngoặc đơn thì nên được viết cách ra một space. Ví dụ: while (true) { ... }

Chú ý: Không nên sử dụng một khoảng trắng giữa tên method và dấu mở ngoặc của nó. Điều này giúp phân biệt giữa các keyword với các câu lệnh gọi method.

Nên để một ký tự trống sau mỗi dấu phẩy ở danh sách các tham số.

Tất cả các toán tử (trừ toán tử “.”) nên được phân cách các toán hạng của nó bằng một ký tự trống. Tuy nhiên không nên sử dụng các ký tự trống giữa toán tử với toán hạng đối với các toán tử đơn nhất như: tăng ("++"), giảm ("--"). Ví dụ:

a += c + d; a = (a + b) / (c * d); while (d++ = s++) { n++; } printSize("size is " + foo + "\n");

Các biểu thức trong câu lệnh for cũng nên được phân tách bởi các ký tự trắng. Ví dụ:

for (expr1; expr2; expr3)

Khi ép kiểu thì cũng phải sử dụng ký tự trống như ví dụ sau: myMethod((byte) aNum, (Object) x); myMethod((int) (cp + 5), ((int) (i + 3)) + 1);

21

Page 22: Coding Convention

STH VIETNAM

10 QUY ƯỚC ĐẶT TÊN (NAMING CONVENTIONS)Tuân theo các quy ước về đặt tên sẽ làm chương trình trở nên dễ đọc và dễ hiểu. Nó còn có thể cung cấp thêm thông tin như nó là một constant, package hay là một class.

10.1 Một số quy ước chung (General Rules)

Phần này sẽ đưa ra một số quy ước chung về đặt tên Source File / variable / control / method.

i. Người lập trình khi đặt tên phải có ý nghĩa, và phải nó phải chỉ ra được mục đích của file / variable / control / method.

ii. Sử dụng terminology applicable to the domain. Nếu người dùng của bạn coi các clients của họ như là các customers, khi đó ta phải sử dụng term Customer cho tên class chứ không dung Client. Rất nhiều developers gặp lỗi tạo ra các generic terms cho các concepts trong khi đã có những perfectly good terms trong industry/domain.

iii. Các định danh (Identifiers) phải càng ngắn càng tốt nhưng không làm lu mờ đi ý nghĩa của nó, nên nằm trong khoảng 20 ký tự trở xuống.

iv. Nên tránh sử dụng các tên gần giống nhau.Ví dụ: Tên biến persistentObject và persistentObjects không nên sử dụng cùng nhau, cũng như là không nên sử dụng hai tên biến anSqlDatabase và anSQLDatabase

v. Không nên sử dụng những tên khó hiểu, kể cả trong trường hợp nó chỉ làm biến đệm hoặc làm biến đếm.Các tên khó hiểu có thể làm tiêu tốn sức lực của người lập trình khi thời gian tiêu tốn cho việc hiểu xem vai trò của variable/control/method đó hơn là hiểu xem chức năng của nó giải quyết được vấn đề gì.

vi. Nên tránh viết tắt tên.Tuy nhiên các nhóm từ đã được quen thuộc, nhiều người biết đến thì nên sử dụng nó. Ví dụ: computeAverage(); // Không nên: compAvg(); generateHTML(); // Không nên: generateHypertextMarkupLanguage();

vii. Tên method không nên có bất cứ một ký tự đặc biệt nào ngoài dấu gạch dưới.Chỉ sử dụng dấu gạch dưới trong trường hợp đặt tên các hằng số

10.2 Class/Interface

Tên của mỗi class/interface phải được bắt đầu bằng một chữ hoa và phải tuân theo quy ước chung của việc đặt tên (xem phần 10.1), ví dụ: class CustomerBean.

Các Exception classes nên thêm chữ Exceptin ở cuối, ví dụ: LMSFunctionalException.

Các Interfaces không có method nào thì nên thêm chữ I ở đầu, ví dụ: IConstants.

Các Abstract classes nên thêm chữ Abstract ở đầu, ví dụ: abstract class AbstractBean.

Các Implementation classes nên thêm chữ Impl ở đầu, ví dụ: class CustomerBOImpl implements CustomerBO.

22

Page 23: Coding Convention

STH VIETNAM

10.3 Biến số (Variables)

Tên biến được bắt đầu với một ký tự thường và phải tuân theo quy ước về đặt tên ở trên (xem phần 10.1). Ví dụ: custName.

Các biến List (thuộc kiểu Collection/List) nên thêm vào cuối chữ List, ví dụ: Collection custList.

Các biến Set (thuộc kiểu Set/HashSet) nên thêm vào cuối chữ Set, ví dụ: Set custSet = new HashSet();

Các biến Map (thuộc kiểu Map/HashMap/TreeMap) nên thêm vào cuối chữ Map, ví dụ: Map custMap = new TreeMap();

Các biến Array có thể thêm vào cuối chữ Array, ví dụ: int[] custIDArray;

Về việc sử dụng tên ID hay Id thì tùy thuộc vào từng ứng dụng.

10.4 Hằng số(Constants)

Khi đặt tên hằng số phải tuân theo các quy ước sau đây: Tuân theo các quy ước đặt tên chung (xem phần 10.1).

Mọi hằng số được tên phải được viết hoa tất cả các chữ và giữa các từ được liên kết với nhau bằng dấu gạch dưới.

Mọi hằng số phải được khai báo static final.

10.5 Phương thức (Methods)

Khi đặt tên các method trong class file phải tuân theo các quy ước sau: Tuân theo các quy ước đặt tên chung (xem phần 10.1).

Tên method phải bắt đầu bằng một chữ viết thường.

Từ đâu tiên của tên method nên sử dụng “động từ”. Ví dụ đây là một số động từ thường dùng:

getCustomerID, setCustomerID

isActive, hasAddresses

findCustomers, searchCustomers

computeSalary, calculateSalary

initializeParameters, initParameters

addCustomer, removeCustomer

insertCustomer, deleteCustomer

updateCustomer, modifyCustomer, amendCustomer

openConnection, closeConnection, saveFile

createBuffer, destroyBuffer

23

Page 24: Coding Convention

STH VIETNAM

startProcess, stopProcess

...

Các động từ nên dử dụng theo cặp với nhau và được sử dụng một cách thích hợp đối với ứng dụng.

Một số methods đặc biệt không bắt đầu với động từ:

Factory methods: newCustomer(), newCustomerBO()

Conversion methods: toString(), toLongPhoneNumber(), toXXX()

24

Page 25: Coding Convention

STH VIETNAM

11 PROGRAMMING PRACTICES

11.1 Providing Access to Instance and Class Variables

Không nên tạo những instance variable hoặc class variable là public trừ phi có một lý do đặc biệt nào đó. Thường thì các instance variables không cần phải hiện vì nó dễ gây ra hiệu ứng phụ khi gọi các method. Một ví dụ cho public instance variables là trường hợp một class có bản chất là một cấu trúc dữ liệu, không có một behavior nào cả. Nói cách khác, nếu bạn muốn sử dụng một struct thay vì một class (nếu Java hỗ trợ struct), thì tương ứng với việc để các instance variable của class đó là public.

11.2 Tham chiếu đến Class Variables và Methods

Tránh sử dụng một object để truy cập tới một class (static) variable hoặc một method. Nên sử dụng tên class. Ví dụ:

classMethod(); //OKAClass.classMethod(); //OKanObject.classMethod(); //AVOID!

11.3 Hằng số (Constants)

Các hằng số không nên được code một cách trực tiếp, trừ trường hợp nó lấy các giá trị như -1, -, 1 để làm counter trong các vòng lặp for.

11.4 Phép gán (Variable Assignments)

Tránh việc gán cho một vài biến có cùng giá trị trên một dòng. Điều này gây khó khăn khi đọc. Ví dụ:

fooBar.fChar = barFoo.lchar = 'c'; // NÊN TRÁNH!Không nên sử dụng toán tử gán ở nơi dễ gây nhầm lẫn với các toán tử so sánh. Ví dụ:

if (c++ = d++) { // AVOID! (Java không chấp nhận) ...}

nên viết là

if ((c++ = d++) != 0) { ...}

Không được sử dụng các lệnh gán lồng nhau nhằm tăng hiệu năng xử lý. Đó là công việc của chương trình dịch. Ví dụ:

d = (a = b + c) + r; // AVOID!nên viết là

a = b + c;d = a + r;

25

Page 26: Coding Convention

STH VIETNAM

11.5 Loggings

Mỗi một ứng dụng Java nên sử dụng một cơ chế logging cấu hình được nào đó mà nó hỗ trợ việc logging ở các mức khác nhau cũng như cho phép bật/tắt việc logging một số mức khi runtime. Ta có thể sử dụng hai loại logging components thường được nhắc tới đó là:

Log4J component từ dự án mã nguồn mở Jakarta, được sử dụng rộng rãi trong các ứng dụng J2EE.

Proximus ClientLog component, được sử dụng rộng rãi trong tất cả các dự án Proximus.

System.out.println() không nên sử dụng cho việc loggings. Các lập trình viên có thể sử dụng nó để debug trong unit tests nhưng phải xóa nó khỏi source sau khi hoàn thành unit test.

11.6 Performance Practices11.6.1Các thao tác với File Các thao tác với file phải được giảm thiểu. Thay vì việc phải đọc đi đọc lại các tham số khác nhau từ một file thì ta nên load toàn bộ tham số từ file đó ra bộ nhớ một lần và sau đó thì đọc nội dung của nó từ bộ nhớ.11.6.2StringBuffer và StringKhi nối các string với nhau, đặc biệt là thông qua vòng lặp, ta nên sử dụng StringBuffer thay cho String để giảm thiểu số lượng String object không cần thiết.11.6.3Xóa nội dung của các structure lớn sau khi sử dụng xongMột việc nên làm sau khi sử dụng các Collection/Map object là phải clear() nội dung của nó đi. 11.6.4Tiết kiệm việc tạo các object mới Khi tạo ra quá nhiều object sẽ chiếm rất nhiều tài nguyên của hệ thống và nó sẽ tác động mạnh đến hiệu năng của ứng dụng. Vì vậy, phải tránh việc tạo ra các object không cần thiết.

11.7 Miscellaneous Practices11.7.1Các dấu ngoặc đơn (Parentheses)Nên sử dụng các dấu ngoặc một cách “rộng rãi” để tránh các vấn đề về độ ưu tiên của toán tử trong các biểu thức phức tạp. Cho dù bạn nắm độ ưu tiên của các toán tử một cách rõ ràng đi nữa nhưng đối với người khác chưa chắc họ đã nắm được như bạn. Do đó, hãy luôn ghi nhớ là dùng các cặp ngoặc đơn sao cho biểu thức của bạn được dễ nhìn nhất.

if (a == b && c == d) // Nên tránh!if ((a == b) && (c == d)) // Nên dùng

11.7.2Các giá trị trả về (Return values)Hãy làm cho cấu trúc chương trình của bạn có ý nghĩa, mục đích. Ví dụ:

if (booleanExpression) { return true;

26

Page 27: Coding Convention

STH VIETNAM

} else { return false;}

thì nên viết là

return booleanExpression;

Cũng giống như if (condition) { var = x;} else { var = y;}

thì nên viết là var = (condition) ? x : y;

11.7.3Biểu thức trước dấu ‘?' trong toán tử điều kiện Nếu biểu thức chứa một toán tử xuất hiện trước dấu ? trong toán tử điều kiện ?: thì nên đặt nó trong cặp ngoặc đơn. Ví dụ:

(x >= 0) ? x : -x;

11.7.4Các comment đặc biệt Sử dụng xxx trong comment để đánh dấu một cái gì đó là giả (bugus) nhưng có hoạt động.Sử dụng FIXME trong comment để đánh dấu một cái gì đó là giả (bugus) và không hoạt động (broken)11.7.5Phương thức toString() Việc overriding toString() để tạo ra một mô tả hữu ích cho một object (ví dụ: kiểu của một object và giá trị của các id duy nhất nào đó mà nó chứa)Để tránh nhầm lẫn, toString() của hai object chỉ bằng nhau khi và chỉ khi equals() trả về giá trị true.11.7.6equals() / hashCode()Nếu một class cung cấp một equals() method, nó cũng phải cung cấp một hashCode() method, với quy ước là hashCode của 2 instantce chỉ bằng nhau khi chúng equals()

27

Page 28: Coding Convention

STH VIETNAM

12 CODE EXAMPLES

12.1 Một ví dụ Java Source File

Ví dụ sau chỉ ra cho thấy định dạng của một Java source file chứa các public class. Các Interfaces cũng được định dạng tương tự. Để biết thêm thông tin chi tiết, xem phần "Class and Interface Declarations" ở trang 4 và "Documentation Comments" ở trang 9

/* * Copyright(C) 2005 SthVietnam Software Company * * $Id: Blah.java,v 1.1 2006/01/11 03:43:05 quangtn Exp $ * */

package java.blah;

import java.blah.blahdy.BlahBlah;

/** * Class description goes here. * * @author quangtn<[email protected]> $Author: quangtn$ * @version $Revision: 1.1 $ */public class Blah extends SomeClass { /* A class implementation comment can go here. */

/** classVar1 documentation comment */ public static int classVar1;

/** * classVar2 documentation comment that happens to be * more than one line long */ private static Object classVar2;

/** instanceVar1 documentation comment */ public Object instanceVar1;

/** instanceVar2 documentation comment */ protected int instanceVar2;

/** instanceVar3 documentation comment */ private Object[] instanceVar3;

/** * ...constructor Blah documentation comment... */ public Blah() { // ...implementation goes here... }

/** * ...method doSomething documentation comment... */

28

Page 29: Coding Convention

STH VIETNAM

public void doSomething() { // ...implementation goes here... }

/** * ...method doSomethingElse documentation comment... * @param someParam description */ public void doSomethingElse(Object someParam) { // ...implementation goes here... }}

29