Ậ Ậ 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ó: Single­entry, single­exit

ướ

ố ượ

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 single­entry, single­exit. 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 User­Defined:

ộ 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

 if­then­elses:  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 đ

Test­Driven 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 (Self­review)

 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