Bài giảng Kỹ thuật lập trình - Chương 5: Lập trình phòng thủ - Lương Mạnh Bá

Lập trình phòng thủ  
<Defensive Programming>  
(3LT-2BT)  
SE-SoICT  
KTLT 5.1  
Last update 09-2010  
DEFENSIVE PROGRAMMING?  
• Xuất phát từ khái niệm defensive driving.  
• Khi lái xe bạn luôn phải tâm niệm rằng bạn không bao  
giờ biết chắc được người lái xe khác sẽ làm gì. Bằng  
cách đó, bạn có thể chắc chắn rằng khi họ làm điều gì  
nguy hiểm, thì bạn sẽ không bị ảnh hưởng ( tai nạn).  
• Bạn có trách nhiệm bảo vệ bản thân, ngay cả khi người  
khác có lỗi  
• Trong defensive programming, ý tưởng chính là nếu  
chương trình (con) được truyền dữ liệu tồi, nó cũng  
không sao, kể cả khi với CT khác thì sẽ bị fault.  
• Một cách tổng quát, lập trình phòng thủ nghĩa là : làm  
thế nào để tự bảo vệ mình khỏi thế giới lạnh lùng, tàn  
nhẫn của dữ liệu không hợp lệ, các sự kiện mà có thể  
"không bao giờ" xảy ra, và các lập trình viên khác ‘sai  
lꢀm’  
SE-SoICT  
KTLT 5.2  
Last update 09-2010  
1. Bảo vệ CT khỏi các Invalid Inputs  
• Trong thực tiễn :“Garbage in, garbage out.”  
• Trong lập trình “rác rưởi vào – rác rưởi ra” là  
điều không chấp nhận  
• Một CT tốt không bao giờ sãn xuất ra rác rưởi,  
bất kể đꢀu vào là gì !  
• Với 1 CT tốt thì :”rác rưởi vào, không có gì ra”,  
“rác rưởi vào, có thông báo lỗi” hoặc “không cho  
phép rác rưởi vào”.  
• Theo tiêu chuẩn ngày nay, “garbage in, garbage  
out” là dấu hiệu của những CT tồi, không an  
toàn  
SE-SoICT  
KTLT 5.3  
Last update 09-2010  
Ba cách để xử lý rác vào  
• Kiểm tra giá trị của mọi dữ liệu từ nguồn bên ngoài  
– Khi nhận dữ liệu từ file, bàn phím, mạng, hoặc từ các  
nguồn ngoài khác, hãy kiểm tra đê đảm bảo rằng dữ  
liệu nằm trong giới hạn cho phép.  
– Hãy đảm bảo rằng giá trị số nằm trong dung sai và  
xâu phải đủ ngẵn để xử lý. Nếu một chuỗi được dự  
định để đại diện cho một phạm vi giới hạn của các giá  
trị (như một ID giao dịch tài chính hoặc một cái gì đó  
tương tự), hãy chắc chắn rằng các chuỗi là hợp lệ  
cho mục đích của nó; nếu không phải từ chối .  
– Nếu bạn làm việc trên 1 ứng dụng bảo mật, hãy đặc  
biệt lưu ý đến những dữ liệu có thể tấn công hệ thống  
:làm tràn bộ nhớ, injected SQL commands, injected  
html hay XML code, tràn số …  
SE-SoICT  
KTLT 5.4  
Last update 09-2010  
Ba cách để xử lý rác vào  
• Check the values of all routine input  
parameters  
– Kiểm tra giá trị của tất cả cá c tham số truyền  
vào cá c hàm cũng cꢀn như kiểm tra dữ liệu  
nhập từ nguồn ngoài khá c  
• Decide how to handle bad inputs  
– Khi phá t hiện 1 tham số hay 1 dữ liệu khô ng  
hợp lệ, bạn cꢀn làm gì với nó ? Tùy thuộc tì nh  
huống, bạn có thể chọn 1 trong cá c phương  
á n được mô tả chi tiết ở cá c phꢀn sau.  
SE-SoICT  
KTLT 5.5  
Last update 09-2010  
2 Assertions  
• 1 macro hay 1 CT con dùng trong quá trình phát  
triển ứng dụng, cho phép CT tự kiểm tra khi  
chạy.  
• Return true >> OK, false >> có 1 lỗi gì đó trong  
CT.  
• VD : Nếu hệ thống cho rằng file dữ liệu về khách  
hàng không bao giờ vượt quá 50 000 bản ghi,  
CT có thể chứa 1 assertion rằng số bản ghi là  
<= 50 000. Khi mà số bản ghi <= 50,000,  
assertion sẽ không có phản ứng gì. Nếu đếm  
hơn 50 000 bản ghi, nó sẽ lớn tiếng “khẳng  
định” rằng có 1 lỗi trong CT.  
SE-SoICT  
KTLT 5.6  
Last update 09-2010  
• Sử dụng assertions để ghi lại những giả thiết được đưa  
ra trong code và để loại bỏ những điều kiện không mong  
đợi. Assertions có thể đc dùng để kiểm tra các giả thiết  
như :  
– Các tham số đꢀu vào nằm trong phạm vi mong đợi (tương tự với  
các tham số đꢀu ra)  
– file hay stream đang được mở (hay đóng) khi 1 CTC bắt đꢀu  
thực hiện (hay kết thúc)  
– 1 file hay stream đang ở bản ghi đꢀu tiên (hay cuối cùng) khi 1  
CTC bắt đꢀu ( hay kết thúc) thực hiện  
– 1 file hay stream được mở để đọc, để ghi, hay cả đọc và ghi  
– Giá trị của 1 tham số đꢀu vào là không thay đổi bởi 1 CTC  
– 1 pointer là non-NULL  
– 1 mảng đc truyền vào CTC có thể chứa ít nhất X phꢀn tử  
– 1 bảng đã đc khởi tạo để chứa các giá trị thực  
– 1 danh sách là rỗng (hay đꢀy) lkhi 1 CTC bắt đꢀu (hay kết thúc)  
thực hiện  
SE-SoICT  
KTLT 5.7  
Last update 09-2010  
• ND cuối không cꢀn thấy các thông báo  
của assertion ;  
• Assertions chủ yếu được dùng trong quá  
trình phát triển hay bảo dưỡng ứng dụng.  
• Dịch thành mã khi phát triển, loại bỏ khỏi  
mã trong sản phẩm >>hiệu quả.  
SE-SoICT  
KTLT 5.8  
Last update 09-2010  
Rất nhiều NNLT hỗ trợ assertions : C++, Java và  
Visual Basic.  
Kể cả khi NNLT không hỗ trợ, thì cũng có thể dễ  
ràng xd  
VD:  
#define ASSERT( condition, message ) {  
if ( !(condition) ) {  
fprintf( stderr, "Assertion %s failed: %s\n",  
condition,message );  
exit( EXIT_FAILURE );  
}
}
SE-SoICT  
KTLT 5.9  
Last update 09-2010  
Guidelines for Using Assertions  
• Sử dụng mꢀ xử lý lỗi với những điều kiện ta  
chờ đợi sẽ xảy ra; Dùng assertions cho các  
ĐK không mong đợi ( không bao giờ xảy ra)  
– Error-handling : kiểm tra với lỗi đꢀu vào  
– Assertions : kiểm tra có bugs trong CT..  
– Error handling hướng tới việc xử lý lỗi, còn assertion  
thì hướng đến việc hiệu chỉnh chương trình , tạo ra  
các phiên bản của PM.  
• Tránh đưa mꢀ xử lý vào trong assertions  
– Điều gì xảy ra khi ta turn off the assertions ?  
SE-SoICT  
KTLT 5.10  
Last update 09-2010  
Guidelines for Using Assertions(tt)  
• Với các hệ thống lớn, assert, và sau đó xử lý  
lỗi  
– Với 1 nguyên nhân gây lỗi xác định, hoặc là dùng  
assertion hoặc error-handling , nhưng không dùng cả  
2. ?  
– Với các HT lớn, nhiều người cùng Pt và kéo dài 5-10  
năm, hoặc hơn nữa ?  
– Cả assertions và error handling code có thể đc dùng  
cho cùng 1 lỗi. Ví dụ trong source code cho Microsoft  
Word, những điều kiện luôn trả về true thì đc dùng  
assertion, nhưng đồng thời cũng đc xử lý.  
– Với các hệ thống cực lớn, ( VD Word) , assertions là  
rất có lợi vì nó giúp loại bỏ rất nhiều lỗi trong quá trình  
PT HT  
SE-SoICT  
KTLT 5.11  
Last update 09-2010  
3. Kỹ thuật xử lý lỗi  
(Error Handling Techniques)  
• Error handling dùng để xử lý các lỗi mà ta  
chờ đợi sẽ xảy ra  
• Tùy theo tình huống cụ thể, ta có thể trả  
về 1 giá trị trung lập, thay thế đoạn tiếp  
theo của dữ liệu hợp lệ, trả về cùng giá trị  
như lꢀn trước, thay thế giá trị hợp lệ gꢀn  
nhất, Ghi vết 1 cảnh báo vào tệp, trả về 1  
mã lỗi, gọi 1 thủ tục hay đối tượng xử lý,  
hiện 1 thông báo hay tắt máy.  
SE-SoICT  
KTLT 5.12  
Last update 09-2010  
Chắc chắn thay vì chính xác  
• Giả sử một ứng dụng hiển thị thông tin đồ họa trên màn hình. Một  
vài điểm ảnh ở góc tọa độ dưới bên phải hiển thị màu sai. Ngày tiếp  
theo, màn hình sẽ làm mới, lỗi không còn.Phương pháp xử lý lỗi tốt  
nhất là gì?  
• Chính xác có nghĩa là không bao giờ gặp lại lỗi  
• Chắc chắn có nghĩa là phꢀn mềm luôn chạy thông, kể cả khi có lỗi  
• Ưu tiên tính chắc chắn để có tính chính xác. Bất cứ kết quả nào đó  
bao giờ cũng thường là tốt hơn so với Shutdown. Thỉnh thoảng  
trong các trình xử lý văn hiển thị một phꢀn của một dòng văn bản ở  
phía dưới màn hình. Khi đó ta muốn tắt CT ? Chỉ cꢀn nhấn trang lên  
hoặc xuống trang, màn hình sẽ làm mới, và sẽ hiển thị sẽ trở lại  
bình thường.  
• Đôi khi, để loại bỏ 1 lỗi nhỏ, lại rất tốn kém. Nếu lỗi đó chắc chắn  
không ảnh hưởng đến mục đích cơ bản của ứng dụng, không làm  
CT bị die, hoặc làm sai lệch kết quả chính, người ta có thể bỏ qua,  
mà không cố sửa để có thể gặp phải các nguy cơ khác.  
• Hiện tại có 1 dạng phꢀn mềm “ chịu lỗi “ tức là loại phꢀn mềm sống  
chung với lỗi, để đảm bảo tính liên tục, ổn định …  
SE-SoICT  
KTLT 5.13  
Last update 09-2010  
4. Xử lý ngoại lệ - Exceptions  
• Exception : bắt các tình huống bất thường và phục hồi  
chúng về trạng thái trước đó.  
• Dùng Ngoại lệ để thông báo cho các bộ phận khác của  
chương trình về lỗi không nên bỏ qua  
– Lợi ích của ngoại lệ là khả năng báo hiệu điều kiện lỗi . Phương  
pháp tiếp cận khác để xử lý các lỗi tạo ra khả năng mà một điều  
kiện lỗi có thể truyền bá thông qua một cơ sở mã không bị phát  
hiện. Ngoại lệ có thể loại trừ khả năng đó.  
• Chỉ dùng ngoại lệ cho những điều kiện thực sự ngoại lệ  
– Exceptions đc dùng trong những tình huống giống assertions—  
cho các sự kiện không thường xuyên, nhưng có thể không bao  
giờ xảy ra  
– Exception có thể bị lạm dụng và phá vở các cấu trúc, điều này  
dễ gây ra lỗi, vì làm sai lệch luồng điều khiển  
SE-SoICT  
KTLT 5.14  
Last update 09-2010  
• Ví dụ : trong các PM ứng dụng, khi xử lý dữ liệu … ( C#)  
try  
{
cmd.ExecuteNonQuery();  
ErrorsManager.SetError(ErrorIDs.KhongCoLoi);  
}
catch  
{
ErrorsManager.SetError(ErrorIDs.SQLThatBai,  
database.DbName,“ten_strore");  
}
VB.NET  
Try  
Return CBO.FillCollection(CType(SqlHelper.ExecuteReader(ConStr,  
"TimHDon", iSoHoaDon), IDataReader),GetType(ThanhToan.ChiTietHDInfo))  
Catch ex As Exception  
mesagebox.show(ex.message)  
End Try  
SE-SoICT  
KTLT 5.15  
Last update 09-2010  
Dim tran As SqlTransaction  
Try  
conn.Open()  
tran = conn.BeginTransaction()  
SqlHelper.ExecuteNonQuery(tran, "ThemHDon",_  
HDInfo.SoHoaDonTC, HDInfo.TenKhach, _  
HDInfo.PhuongThucTT)  
iMaHD = GetMaHoaDon_Integer(tran)  
For Each objCT In arrDSCT  
SqlHelper.ExecuteNonQuery(tran, "ThemChiTietHD",  
objCT.ChiTiet, _  
objCT.SoTienVND, iMaHDP)  
Next  
tran.Commit()  
Catch ex As Exception  
tran.Rollback()  
End Try  
SE-SoICT  
KTLT 5.16  
Last update 09-2010  
• Phục hồi tài nguyên khi xảy ra lỗi ?  
– Thường thì không phục hồi tài nguyên  
– Nhưng sẽ hữu ích khi thực hiện các công việc nhằm  
đảm bảo cho thông tin ở trạng thái rõ ràng và vô hại  
nhất có thể  
– Nếu các biến vẫn còn đc truy xuất thì chúng nên đc  
gán các giá trị hợp lý  
– Trường hợp thực thi việc cập nhật dữ liệu, nhất là  
trong 1 phiên – transaction – liên quan tới nhiều bảng  
chính, phụ, thì việc khôi phục khi có ngoại lệ là vô  
cùng cꢀn thiết. ( rollback )  
SE-SoICT  
KTLT 5.17  
Last update 09-2010  
5.Gỡ rối – debbuging  
• Các chương trình đã viết có thể có nhiều lỗi ? – tại sao phꢀn mềm  
lại phức tạp vây ?  
• Sự phức tạp của CT liên quan đến cách thức tương tác của các  
thành phꢀn của CT đó, mà 1 phꢀn mềm lại bao gồm nhiều thành  
phꢀn và các tương tác giữa chúng  
• Nhiều kỹ thuật làm giảm số lượng các thành phꢀn tương tác :  
– Che giấu thông tin  
– Trừu tượng hóa …  
• Có các kỹ thuật nhàm đảm bảo tính toàn vẹn thiết kế phꢀn mềm  
– Documentation  
– Lập mô hình  
– Phân tích các yêu cꢀu  
– Kiểm tra hình thức  
• Nhưng chưa có 1 kỹ thuật nào làm thay đổi cách thức xây dựng  
phꢀn mềm => luôn xuất hiện lỗi khi test, phai loại bỏ = gỡ rối !  
SE-SoICT  
KTLT 5.18  
Last update 09-2010  
• LTV chuyên nghiệp cũng tốn nhiều thời gian cho gỡ rối !  
• Luôn rút kinh nghiệm từ các lỗi trước đó  
• Viết code và gây lỗi là điều bình thường – vấn đề làm  
sao để không lặp lại!  
• LTV giỏi là người giỏi gỡ rối  
• Gỡ rối không đơn giản, tốn thời gian => cꢀn tránh gây ra  
lỗi. Các cách làm giảm thời gian gỡ rối là :  
– Thiết kế tốt  
– Phong cách LT tốt  
– Kiểm tra các ĐK biên  
– Kiểm tra các “khẳng định” – assertion và tính đúng đắn trong mã  
nguôn  
– Thiết kế giao tiếp tốt, giới hạn việc sử dụng dữ liệu toàn cục  
– Dùng các công cụ kiểm tra  
• Phòng bệnh hơn chữa bệnh !!  
SE-SoICT  
KTLT 5.19  
Last update 09-2010  
• Động lực chính cho việc cải tiến các ngôn ngữ LT là cố  
gắng ngăn chặn các lỗi thông qua các đặc trưng ngôn  
ngữ như :  
– Kiểm tra các giới hạn biên của các chỉ số  
– Hạn chế không dùng con trỏ, bộ dọn dẹp, các kiểu dữ liệu chuỗi  
– Xác định kiểu nhập/xuất  
– Kiểm tra dữ liệu chặt chẽ.  
• Mỗi ngôn ngữ cũng có những đặc tính dễ gây lỗi : lệnh  
goto, biến toàn cục, con trỏ trỏ tới vùng không xác định,  
chuyển kiểu tự động…  
• LTV cꢀn biết trước những đặc thù để tránh các lỗi tiềm  
ẩn, đồng thời cꢀn kích hoạt mọi khả năng kiểm tra của  
trình biên dịch và quan tâm đến các cảnh báo  
• Ví dụ : so sánh C,Pascal, VB …  
SE-SoICT  
KTLT 5.20  
Last update 09-2010  
Tải về để xem bản đầy đủ
ppt 44 trang Thùy Anh 15060 Free
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Kỹ thuật lập trình - Chương 5: Lập trình phòng thủ - Lương Mạnh Bá", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

File đính kèm:

  • pptbai_giang_ky_thuat_lap_trinh_chuong_5_lap_trinh_phong_thu_lu.ppt