Ỹ
Ậ Ậ
K THU T L P TRÌNH
BM CNPM – Khoa CNTT –
HVKTQS
10/2012
Outline
ị
ậ
ẫ
ủ
ử
ể
ậ
ụ ậ
ả
ể
L ch s phát tri n c a các m u hình l p trình
Các nguyên lý l p trình
Các công c l p trình
ồ
ể
Phát tri n mã ngu n incremental
ồ
Qu n lý mã ngu n
ồ
Ki m tra mã ngu n
Các đ đoộ
ớ
ệ
Gi
i thi u chung
ể ể ượ
c ti n hành đ tri n khai
ề
ưở ả
ng c hai
ế
ậ
L p trình đ
ầ
ế ế
t k ph n m m.
thi
ậ ậ
ỹ
ể ẽ ả
ả ử
ậ
Tuy nhiên, th i gian dành cho l p trình
ờ
ng đ i ít h n th i gian dành cho ki m
K thu t l p trình s nh h
quá trình ki m th và b o trì.
ờ
ớ
ườ
t
ử
th và b o trì.
ể
Tính d đ c/hi u là m c tiêu hàng đ u
ụ ể ầ
ố
ả
ễ ọ
ậ
ủ
c a khâu l p trình.
ậ
ấ
L p trình c u trúc
LTCT b t đ u t
ắ ữ ằ
ầ ừ
ạ
nh ng năm 70 nh m
ụ
m c đích t o ra các code mà không có
“goto”
ủ
Ngoài ra, múc đích khác c a LTCT là
tr giúp quá trình quá trình ki m ch ng
mã ngu n. ồ
ứ ể ợ
ậ
ấ
L p trình c u trúc
ầ
ệ
ấ
ệ
ỉ ơ
Câu l nh không ch đ n thu n là gán
ơ ả
Ba c u trúc l nh c b n:
Selection: if B then S1 else S2 if B then S1
Iteration: While B do S
repeat S until B
Sequencing: S1; S2; S3;...
Luôn luono có: Singleentry, singleexit
ậ
ướ
ố ượ
L p trình h
ng đ i t
ng
ấ
ượ
ậ ậ
ệ ố ượ
ng. OOP đ
ộ
ơ
ầ
ả
ề
ữ
ề
ơ
ề ậ
ố ượ
ơ
ở ộ
ư
ề ở ậ
ầ
ng ph n m m
ườ
ơ
ằ
ướ
ả ượ
ộ ỗ ự
ế
ằ
ả
c đó.
c, đây là khái ni m và là m t n l c nh m gi m nh các thao tác vi
ả
ậ
ễ ế
i còn cho r ng OOP d ti p thu h n cho nh ng ng
ng pháp tr
M t cách gi n l
ụ
ẹ
i l p trình, cho phép h t o ra các ng d ng mà các y u t
ố
ế
ố ượ
ươ
ươ
ư
ớ
ng tác v i các đ i t
ệ
ứ
ọ ạ
ố
ng trình đó gi ng nh là t
ữ
ế ợ
ữ
ư
ộ
t mã
ể
bên ngoài có th
ậ
ng v t lý.
ữ ệ
ng có m t tên riêng bi
ộ
ộ ơ
c nhìn nh n nh là m t đ n v duy nh t. M i đ i t
ố ượ
ấ
ế
ư ậ
ượ
ủ
ế
ị
ng đó đ
ữ ệ
ủ
ử
ng trong m t ngôn ng OOP là các k t h p gi a mã và d li u mà chúng
ấ ả
ỗ ố ượ
t c
ng
ả ờ
i
ử
ườ
ế
ế
ậ
ng khác hay đ n môi tr
ng.
nh ng năm 1980.
ả
ữ ệ
ẹ
ả
ắ
ả
ỗ ợ
c xem là giúp tăng năng su t,
Là kĩ thu t l p trình h tr công ngh đ i t
ằ
ạ
ứ
đ n gi n hóa đ ph c t p khi b o trì cũng nh m r ng ph n m m b ng cách cho
ậ
b c cao h n. Ngoài ra, nhi u
phép l p trình viên t p trung vào các đ i t
ườ
ớ ọ
i m i h c v l p trình h n là các
ng
ươ
ph
ộ
ườ ậ
cho ng
ớ
ươ
ng tác v i các ch
t
ố ượ
ữ
Nh ng đ i t
ệ
ậ
ượ
t và t
đ
ỗ ố ượ
ế
các tham chi u đ n đ i t
c ti n hành qua tên c a nó. Nh v y, m i đ i t
ả
có kh năng nh n vào các thông báo, x lý d li u (bên trong c a nó), và g i ra hay tr l
ố ượ
đ n các đ i t
ữ
ờ ừ
Ra đ i t
ấ
Che d u thông tin, đ m b o tính toàn v n, đúng đ n c u d li u
ấ
Che d u thông tin
ầ
ử ụ
ộ ố ấ
Ph n m m luôn luôn s d ng m t s c u
ữ
ữ ệ
ấ
M i m t c u trúc d li u s đ
c truy xu t
ỗ
ở
ề
ữ ệ
ộ ấ
ộ ố ữ
ạ
ẽ
ậ
ấ
ể ư
trúc d li u đ l u tr thông tin.
ẽ ượ
b i m t s h u h n các thao tác
ể
(operations). Các thao tác khác s không th
ượ
c => đây chính là
truy nh p thông tin này đ
nguyên lý che d u thông tin.
ữ
Ph n l n các ngôn ng LT HĐT cho phép
ầ ớ
ề
làm đi u này
ậ
Các nguyên lý l p trình
ệ
ậ
ấ ớ ờ ớ ủ
Nhi m v chính c a l p trình viên là
ỗ
i nh t v i th i gian ít
K năng l p trình thu nh n đ
ụ
ạ
t o ra code v i ít l
nh t.ấ
ỹ ậ ượ c thông
t code.
ụ ộ ộ ậ qua th c t
L p trình t
ậ
ự ế ế
vi
ố
t không ph thu c vào m t
ữ ụ ể ngôn ng c th
ộ ố ư
ự ế
M t s l u ý th c t
ề
ử ụ
ử ụ
ấ
ườ
ẩ
ấ
ử ụ
ườ
ề
ợ
Control Constructs: S d ng nhi u
c u trúc singleentry, singleexit. Tăng
ng s d ng các c u trúc chu n.
c
ệ
Gotos: Không nên s d ng các l nh
ng h p
ấ ắ
goto quá nhi u. Trong các tr
b t đ c dĩ.
ộ ố ư
ự ế
M t s l u ý th c t
Che d u thông tin:
ấ ượ nên đ ử ụ
c s d ng
ậ
Ki u DL UserDefined:
ộ
r ng rãi. Truy nh p thông tin nên theo
ế
ơ
c ch hàm.
ể ế
ử ụ ể
ự ị ữ
N u ngôn ng
LT cho phép thì nên s d ng các ki u
DL t đ nh nghĩa.
ộ ố ư
ự ế
M t s l u ý th c t
ặ
Nesting: Nên tránh các L p sâu (deep nesting). For
example, consider the following construct of nested
ề
ệ
ế
N u các đi u ki n là không liên k t disjoint thì ta
ifthenelses:
if C1 then S1
else if C2 then S2
else if C3 then S3
else if C4 then S4;
ế
nên:
if C1 then S1;
if C2 then S2;
if C3 then S3;
if C4 then S4;
ộ ố ư
ự ế
M t s l u ý th c t
ệ
ề
ớ
ố
ả ế ứ
ậ
ế
ướ ớ
ế
ể
ệ
ả
ử ụ
Module Size: Vi c s d ng hàm v i nhi u
ẩ
bi n s ph i h t s c c n th n (>= 100). Kích
c l n có th làm cho vi c qu n lý k t
th
ế ố
dính và k t n i khó khăn.
ộ
ấ
ơ
ệ
ặ
ả
ẩ
ố
ượ
ỳ
Module Interface: (rule of thumb), b t k
ề
ệ
m t giao di n module mà có nhi u h n 5
ậ
t c n th n và nên
tham s thì ph i đ c bi
ỏ ơ
đ
c chia thnàh nhièu module nh h n
ộ ố ư
ự ế
M t s l u ý th c t
Side Effects: Hi n t
ổ
ổ ạ
ị
ổ ế ả
ệ ượ
ng thay đ i tr ng
thái CT mà không thay đ i giá tr tham
ườ
ố
ng x y ra khi ta thay đ i bi n
s . Th
toàn c c.ụ
Robustness: X lý t
ử ố ệ ề
t các đi u ki n
ạ ệ ngo i l .
ộ ố ư
ự ế
M t s l u ý th c t
Switch Case with Default: Đ m b o
ả ả
VD:
switch (i){
case 0 : {s=malloc(size)
}
s[0] = y; /* NULL dereference if default
ủ ổ ị hành vi c a CT n đ nh.
occurs */
ộ ố ư
ự ế
M t s l u ý th c t
ắ ỗ
ặ
i,
Empty Catch Block: nên có ch n b t l
ể ố
tránh đ tr ng.
VD:
try {
FileInputStream fis = new
FileInputStream (" InputFile ");
}
catch (IOException ioe) { }
// not a good practice
ộ ố ư
ự ế
M t s l u ý th c t
Empty if, while Statement: Không làm
VD:
if (x == 0) {} /* nothing is done after
ệ gì sau các câu l nh này. Nên tránh.
else {
:
}
checking x */
ộ ố ư
ự ế
M t s l u ý th c t
ị ả ề
Read Return to Be Checked: Giá tr tr v
ọ
ượ
ể
c ki m tra
ệ
sau l nh đ c nên đ
if read
VD:
is more
from scanf()
then
than
expected,
it may cause a buffer
overflow. Hence, the value of read should be
checked before accessing the data read.
(This is the reason why most languages
provide a return value for the read operation.)
ộ ố ư
ự ế
M t s l u ý th c t
Return from Finally Block: One should not return
from finally block, as it can create false beliefs. For
example, consider the code
public String foo() {
try {
throw new Exception( "An Exception" );
}
catch (Exception e) {
throw e;
}
finally {
return "Some value ";
}
}
ộ ố ư
ự ế
M t s l u ý th c t
ườ
ng, s t n t
ẽ ồ ạ
i
ệ ữ
ố
Correlated Parameters: Thông th
ố
m i quan h gi a các tham s .
VD: in the code segment given below, “length” represents
the size of BUFFER. If the correlation does not hold, we can
run into a serious problem like buffer overflow (illustrated in
the code fragment below).
ố
ể
ậ
ế
ệ
ả
ơ
Vì v y, nên ki m tra m i quan h này h n là gi
thi
t
ỏ
nó đã th a mãn.
void (char *src , int length , char destn []) {
strcpy (destn , src); /* Can cause buffer overflow if length >
MAX_SIZE */
}
ộ ố ư
ự ế
M t s l u ý th c t
ệ ự ượ ể
ướ ữ
Trusted Data Sources: ki m tra d
c khi truy
c th c hi n tr
ậ
Give Importance to Exceptions: Chú
ệ
li u nên đ
nh p chúng
For example, while doing the string copy
operation, we should check that the source
string is null terminated, or that its size is
as we expect.
ạ ệ ề ể ọ tr ng đi u khi n ngo i l .
ẩ
ồ
Chu n mã ngu n
Th c t
ề
ể ọ
Vì v y c n nh ng chu n m c nh t đ nh
ố ấ
ồ
trong vi c đ c hi u mã ngu n.
ự
ữ ự ế
là chúng ta tiêu t n r t nhi u
ệ
ầ ấ ị ậ ẩ
ậ
trong l p trình
ề ặ
ẩ
Chu n v đ t tên
ặ
ướ
ư
ổ ế
c đ t tên ph bi n nh sau:
Qui
Package names should be in lowercase: Tên package nên dùng ch ữ
ườ
ụ
th
ng (ví d : mypackage, edu.iitk.maths).
Type names should be nouns and should start with uppercase: Tên
ừ
ắ ầ
ữ
ụ
ằ
ể
và b t đ u b ng ch hoa(ví d : Day, DateOfBirth,
ki u nên là danh t
EventHandler).
ế
Variable names should be nouns starting with lowercase: Tên bi n nên
ữ ườ
ắ ầ
ừ
ằ
và b t đ u b ng ch th
là danh t
ứ
ng (e.g., name, amount).
ằ
ầ
ộ
Constant names should be all uppercase: Tên h ng c n ch a toàn b
ữ
các ch hoa (e.g., PI, MAX ITERATIONS).
ứ
ng th c
ữ ườ
ắ ầ
ừ
ộ
Method names should be verbs starting with lowercase: Ph
ằ
và b t đ u b ng ch th
ươ
ng (e.g., getValue()).
nên là đ ng t
ớ
ạ
Exception classes should be suffixed with Exception: Tên các l p ngo i
ệ
ế
l
nên k t thúc b i h u t
ở ậ ố Exception (e.g., OutOfBoundException)
ướ
Qui
ề ặ
c v đ t tên
ỉ ườ
ng minh (e.g., “private int
Bi n Private nên ch t
ộ
Bi n v i ph m vi r ng nên có tên dài và ng
i;
ượ
ặ
ạ
bi n ch y vòng l p nên đ
ử ụ
ặ
ượ
ế
ượ ạ
c l
c đ t tên là i, j, k, ….
c s d ng cho các bi n bool và
ẫ
ể
ế
value ”)
ế
ớ
ạ
ế
ề ố is nên đ
ươ
ứ
ử ụ
ượ
ế
ỉ
ầ
ng th c đ thánh nh m l n (e.g., isStatus
ủ
c s d ng thay cho tên status); bi n ch ph
ị
Ti n t
các ph
nên đ
đ nh negative boolean c n tránh.
ầ
ể ử ụ
T ừ compute có th s d ng cho các hàm tính toán.
ướ
Qui
c Files
ướ ề ặ ố ố
i m t s qui ữ
c v đ t tên và d
VD:
Java source
files should have
the
extension .java—this is enforced by most
compilers and tools.
ồ ạ
T n t
ệ ệ
li u t p.
Kích th
ướ ỏ ơ ộ
ự ặ ệ tránh kí t c dòng nên nh h n 80 c t,
đ c bi t.
ướ
ề
Qui
c v Statements
ướ
c chung đáng k .
ế
ể
ở ạ ạ ơ
ượ
ạ
c kh i t o t
i n i khai báo và nên đ
c khai báo trong ph m
Không có qui
Các bi n nên đ
ỏ
ượ
ể
ấ
vi nh nh t có th .
ạ ệ
ế
ớ
ộ
ạ ệ
ượ
ở
Khai báo các bi n liên quan v i nhau cùng trong m t đo n l nh. Các bi n
các đo n l nh khác nhau.
ế
không liên quan đ n nhau nên đ
c khai báo
ể
ế
ủ ớ
ệ
ặ
ộ
ỉ ử ụ
ế
ở ạ
ướ
ặ
c kh i t o ngay tr
Các thu c tính c a l p không nên đ public.
ể
ặ
Ch s d ng các l nh ki m tra vòng l p trong vòng l p for.
ượ
c vòng l p.
Các bi n vòng l p nên đ
ử ụ
ử ụ
do ... while.
ặ
break và continue trong vòng l p.ặ
ấ
ứ
ứ ạ
ử ụ
ế
ệ
ạ
ờ ể
ự
ứ
ệ
ề
ể
ệ
Tránh s d ng
Tránh s d ng c u trúc
ề
ể
Tránh các bi u th c đi u ki n ph c t p – nên s d ng các bi n boolean t m
ế
th i đ thay th .
Tránh các l nh th c thi trong bi u th c đi u ki n.
ề
c v Commenting and
ướ
Qui
Layout
Chú thích d ng text đ cho ng
ườ ọ ể i đ c
ễ ể
ứ ủ
Chú thích c n gi ụ ể
i thích c th ch c
ả
ố ủ
ạ
d hi u code c a mình.
ầ
năng, tham s c a CT
ươ ủ ng trình sáng s a
Layout giúp cho ch
có c u trúc rõ dàng
ấ
ầ
ể
Phát tri n Code tăng d n
(Incrementally)
ắ ầ ộ ố
Ho t đ ng l p trình b t đ u khi m t s
M i module s do m t ho c nhi u l p
ệ
ậ
ạ ộ
ế ế
thi
t k hoàn thành.
ỗ ặ ẽ ề ậ
ộ
ả
trình viên đ m rnhi m.
ậ ầ
ả
ầ
Chính vì v y mà nhu c u qu n lý qui
ấ
trình này là r t cao. Trong ph n này, ta
tham kh o mô hình tăng d n
ả ầ
ế
ầ
Ti n trình tăng d n
LT cho module,
ẻ
ử
sau đó ki m th ,
ử ỗ
i. Sau
và s a l
c ượ
đó Code đ
ể ả ế
i đ n
chuy n t
ậ
ộ
các b ph n
khác trong d ự
án.
ế
ướ
ự ệ
Ti n trình h
ng s ki n
ế
ế
ộ
ậ
ướ
c và sau
ế
c vi
ượ
t các
ớ
c, sau đó m i
ế
ượ
t sau
ị
c các k ch
t qua đ
ộ
ệ ừ
ướ
t
c qua đ
ệ
TestDriven Development
ổ
ậ
(TDD) là m t cách ti p c n ph
bi n trong l p trình.
ế
Thay vì vi
t code tr
ự
đó xây d ng các test case
ử
ể
ể
đi m ki m th code, trong TDD
ườ ậ
i l p trình viên vi
ng
ả
ị
ướ
k ch b n test tr
ế
t code, code đ
vi
ả ượ
ph i v
ả
b n test này.
ự
ượ
c th c
Toàn b quá trình đ
ả
ị
c, các k ch b n
hi n t ng b
ự
ự
ượ
c xây d ng d a trên
test đ
ượ
ế
ặ ả
c vi
, còn code đ
các đ c t
ả
ị
ượ
ả ượ
c k ch b n
ph i v
ể
ượ
ế
test. Ti n trình TDD đ
c th
hi n trên hình Figure 7.2.
ế
ậ
ặ
Ti n trình l p trình c p Pair
Programming
ậ ặ ượ
Trong l p trình theo c p, code đ
ặ
ở ế
ả
ườ
ẽ ượ ệ c
ứ
ậ
t b i m t c p l p trình viên ch
i. Theo đó,
ố
c phân b
=>Chi phí cao.
ộ
vi
ộ
ở
không ph i b i m t ng
ế
t code s đ
công vi c vi
ặ ậ
ừ
cho t ng c p l p trình viên.
ự
ả
Xây d ng và qu n lý Source
Code
ườ
ộ ự
ườ
Trong m t d án th
ộ
ể ạ
ị
ề
ề
i khác nhau cùng
ng có nhi u nhóm ng
ớ
ệ
ỗ ậ
ể
tham gia phát tri n code. M i l p trình viên làm vi c v i m t file
ớ
ẽ ượ
ữ
ồ
c biên d ch v i nhau đ t o
mã ngu n, nh ng file này s đ
ầ
nên ph n m m.
ườ
ậ
ể
Trong quá trình phát tri n code, các l p trình viên th
ư
ồ
ọ ạ
ổ
ọ ạ
ng luôn
ữ
thay đ i các file mã ngu n do h t o ra, cũng nh nh ng file
không do h t o ra.
ớ
ể
ấ ả
ồ
V i m c đích ki m soát t
ụ
ổ ủ
ụ ể
ư
ồ
ườ
ượ
t c các file mã ngu n và quá trình
thay đ i c a chúng, các công c ki m soát mã ngu n nh CVS
trong Linux (www.cvshome.org) hay Visual Source Safe (VSS)
(msdn.microsoft.com/vstudio/previous/ssafe)
trong Windows
th
ử ụ
c s d ng.
ng đ
Các thao tác chính
Get a local copy.
Make changes to file(s).
Get reports.
ậ
ậ
ổ
C p nh t thay đ i – refactoring
Thay đ i c u trúc bên trong mà không
ủ ổ ấ
ổ làm thay đ i hành vi c a PM.
ự ầ
ế
ế
t
ế ố ẫ
Y u t
d n đ n s c n thi
ổ
ử
s a đ i
ả
ậ
ươ
Duplicate Code.
Long Method.
ứ
ng th c dài
Long Class.
ố
Long Parameter List.
ổ
Switch Statements.
Speculative Generality.
ế ố
Too Much Communication
1. Nh n b n code
2. Ph
ớ
3. L p dài
4. Dánh sách tham s dài
ệ
5. các câu l nh Switch
6. T ng quát hóa
ề
7. Quá nhi u k t n i
Between Objects.
ề
ệ
Message
ử
8. Dây chuy n g i
thông đi p
Chaining.
Thanh tra mã ngu nồ
ượ
Thanh tra Mã ngu n đ
ườ ậ
ng
ự
ồ
i l p trình và dành cho ng
ị
ớ
ộ ế
ệ
ở
c th c hi n b i
ườ ậ
i l p trình.
ề
Là m t ti n trình v i các qui đ nh v vai trò rõ
ràng.
ọ
ữ ệ
ứ
ỗ
i defects.
Tr ng tâm tìm ra l
ể
ạ
ượ
i và dùng đ
c ghi l
D li u thanh tra đ
ả ủ
ộ ệ
đánh giá m c đ hi u qu c a quá trình
thanh tra.
ậ
ạ
ế
L p k ho ch
ụ
ế
ậ
ạ
ẩ
ị
ể
ạ
ủ
M c tiêu c a giai đo n l p k ho ch là đ
chu n b cho thanh tra.
ậ
ượ
Đ i thanh tra đ
ủ
ồ
ầ
ọ
ấ
i,
Đ i thanh tra nên bao g m ít nh t ba ng
ố
ồ
ặ
ườ
m c dù đôi khi có b n ho c năm thành viên.
ẽ
ộ
c thành l p s bao g m các
ậ
l p trình viên mà code c a h đang c n xem
xét.
ộ
ặ
ộ
ườ
ụ
ả
ộ
Đ i thanh tra ph i có m t ng
i ph trách.
ự ể
T ki m tra (Selfreview)
Ng
ự ể ủ ồ i LT t ki m tra mã ngu n c a
ườ
mình
ể
ọ
H p Ki m tra theo nhóm
Nh m đ a ra danh sách chung v các
ề
ư
ằ
ỗ ủ
i c a CT
l
ả ậ ữ ử ề ả
Th o lu n v kh năng s a ch a
ể
Ki m tra theo nhóm
Phép đo
ữ
ế
ệ
ố ố
ử
ố ượ
ự
ượ ườ ng đ c dùng c code: th
ng d a trên s l
ng toán t
ượ
l
h ngạ
ướ
Kích th
ướ ượ
c l
ng chi phí.
trong
ệ
ố
ổ ế
Ph bi n: S dòng l nh
ộ
ụ
ế
ạ
H n ch : Ph c thu c vào ngôn ng
ệ
ử ụ
ầ ớ
Ph n l n là s d ng vi c đ m dong fl nh.
ướ
ệ
c
Tuy nhiên, hi n nay đã có m t s pp
và toán
Phép đo
ể ệ
ủ
ứ ạ
ng c u trúc th hi n các nhánh c a
ố ượ
ượ
ử ụ
ộ
S l
c s d ng trong m t
Đ ph c t p:
ấ
ố ượ
FOC (follow of control),
ế
ng bi n đ
module – live variables
ộ
ủ
Đ sâu c a nesting
ộ
S l
ế
ỏ
K tthúc. Câu h i
ệ
ả
Tài li u tham kh o
ề
ầ
ậ
ườ ị
ộ
ệ
R. Pressman, K ngh ph n m m. T p 1, 2,
i d ch:
3. NXB Giáo d c, Hà N i, 1997 (Ng
Ngô Trung Vi
ỹ
ụ
t).ệ
Pankaj Jalote, An Integrated Approach to
Software Engineering, Third Edition, Springer.
Chapter 9.
ế
ậ
Đoàn Văn Ban. Phân tích, Thi
ố ượ
ế
t k và L p
ố
ng 1997 Nxb Th ng kê
ệ
ướ
trình H ng đ i t
t nam.
Vi