Professional Documents
Culture Documents
MỤC LỤC
A. MỞ ĐẦU
I. LÝ DO CHỌN ĐỀ TÀI
Ngày nay, hàng triệu máy tính được ra đời cùng các hệ phần mềm để phục
vụ các hoạt động cho cá nhân, tập thể, cơ quan, quốc gia.... Dường như con
người chúng ta ngày càng phụ thuộc hơn vào máy tính, vào các hệ phần mềm.
Mà yêu cầu của khách hàng về phần mềm không phải lúc nào cũng giống
nhau, yêu cầu đó ngày càng cao hơn. Khi tham khảo qua truyền hình, qua
internet...tôi thấy, hiện nay có hàng loạt phần mềm Việt Nam ra đời. Nhưng đặt
câu hỏi tại sao, trong những phần mềm đó, có bao nhiêu phần mềm lớn, phần
mềm đáp ứng mọi nhu cầu của khách hàng ? Phải chăng vấn đề chất lượng của
một phần mềm vẫn chưa được chú trọng một cách thích đáng ?
Trong quy trình phát triển phần mềm, theo [5] thiết kế phần mềm là bước
được coi là “Nơi chất lượng phần mềm được nuôi dưỡng trong quá trình phát
triển, cung cấp cách biểu diễn phần mềm có thể xác nhận về chất lượng, là cách
duy nhất mà chúng ta có thể chuyển hóa một cách chính xác các yêu cầu của
khách hàng thành sản phẩm hay hệ thống phần mềm cuối cùng”. Còn theo [3] thì
“Trong ba giai đoạn: thiết kế, cài đặt và bảo trì thì thiết kế là giai đoạn quan
trọng nhất, chịu trách nhiệm đến 80% đối với sự thành công của một sản phẩm.
Cài đặt là việc thực thi những gì đã thiết kế. Nếu trong quá trình cài đặt có xuất
hiện vấn đề thì phải quay lại sửa bản thiết kế. Quá trình thiết kế tốt là cơ sở để
quản lý và giảm chi phí cho công việc bảo trì phần mềm sau này”.
Vậy, thiết kết phần mềm là bước đầu tiên để đảm bảo chất lượng phần
mềm. Nhưng hiện nay các tài liệu liên quan đến chất lượng thiết kế phần mềm
vẫn còn mang tính chất lý thuyết chung chung, chưa dễ hiểu, rõ ràng. Mặt khác,
qua tìm hiểu trên internet và qua các kết quả thiết kế phần mềm của các sinh viên
khoa tin học, khóa học 2007-2010 trường ĐHSP Huế tôi thấy còn gặp nhiều sai
sót để đạt một thiết kế phần mềm tốt. Vấn đề đánh giá chất lượng thiết kế phần
mềm vẫn còn mơ hồ đối với người làm thiết kế phần mềm.
kế phần mềm sưu tầm được để hiểu thêm về thiết kế phần mềm. Nếu những phần
nào chưa rõ thì tôi nhờ các bạn viết phần mềm đó giải thích giùm.Và tât nhiên
tôi đã nhận được sự hướng dẫn từ thầy giáo hướng dẫn để từ đó xác định được
đề tài này nên viết những gì, làm những gì...
Gape-Jones (1980) đưa ra 7 mức kết dính theo thứ tự tăng dần sau đây:
- Kết dính gom góp :
- Kết dính lôgic
- Kết dính thời điểm
- Kết dính thủ tục
- Kết dính truyền thông
- Kết dính tuần tự
- Kết dính chức năng
a. Kết dính gom góp :
Các thành phần không liên quan với nhau, song lại bị bó vào một thành
phần. Tôi xin đưa ra ví dụ đơn giản, khi ta gom các câu lệnh không liên quan tới
nhau để tạo thành 1 hàm nhập trong c++ như sau :
Class NhanSu
{ …
Void nhap()
{
cout <<”nhap hoten: ” ; gets(hoten); Kết dính
gom góp
cout <<”nhap ngay sinh: ” ; gets(ngaysinh);
cout << ”nhap dia chi nha: ”; gets(diachi)
}
}
Rõ ràng, độ kết dính dạng này của nó rời rạc và xấu nhất.
b. Kết dính lôgic (logical cohesion)
Các thành phần làm chức năng logic tương tự. Ví dụ như các hàm xử lí lỗi
chung, cập nhật…
Cụ thể hơn, tôi xin đưa ra một đoạn chương trình viết bằng c++:
thêm n NhanSu vào hệ thống trong chương trình quản lý nhân sự trường
Đại học.
Hay một ví dụ khác trong phần thiết kế Nút sửa dữ liệu ở bảng
Cap_Nhat_Ho_So viết bằng ngôn ngữVb.net, Phần mềm quản lý tin 3b
[8’]
My.Application.DoEvents()
Loop While frm.Visible = True ‘trong khi bảng frm còn
mở thì tiếp
tục thì
DataGridView1
tiếp tục thực hiện.
Dim h As New DataSet khai báo 1
QRY("select * from db_hoso where maso='" & frm.MS & "'", h,
"hoso")
DataGridView1.CurrentRow.Cells("maso").Value =
h.Tables("hoso").Rows(0)("maso")
DataGridView1.CurrentRow.Cells("hoten").Value =
h.Tables("hoso").Rows(0)("hoten") ‘ cập nhật dữ liệu với mã
số, họ tên mới khi khách hàng đồng ý lưu
frm.Dispose() ‘ đóng bảng frm
End Sub
Ở đây các câu lệnh đưa ra để kiểm tra các trường hợp để có thể sửa dữ liệu
hay không. Cụ thể các lệnh được giải thích rõ ở trên. Các lệnh if và do - loop
while ở trên đều có chức năng là kiểm tra các điều kiện để sửa dữ liệu hay
không. Vì vậy ở đây có sự kết dính logic.
Qua đây ta cũng thấy mức kết dính này được đánh giá chất lượng thiết kế
của nó vẫn tốt.
c. Kết dính thời điểm (temporal cohesion).
Các thành phần hoạt động cùng thời điểm.
Ở ví dụ thêm nhân sự tôi đưa ra trên, các câu lệnh trong trường hợp
chon = 1 sau:
For (i=0; i<n; i++)
{ …
{
case 1: {GiaoVien p;
NS[i]=&p ;
NS[i]-nhap()
}
}
Trong trường hợp biến chon = 1 này, con trỏ p là kiểu GiaoVien. NS[i]
được gán bằng địa chỉ của p và NS[i] truy xuất đến hàm nhập trong class
GiaoVien. Và các thành phần này sẽ cùng kết thúc sau khi thoát khỏi vòng lặp.
Hay tôi xin đưa ra một ví dụ về cấp phát bộ nhớ ta sẽ thấy rõ hơn :
Class NhanSu
{ char * hoten;
public:
Void nhap()
{
NhanSu(const char *s, const char *s1, const char *s2)
{ hoten= new char[strlen(s) + 1];
Strcpy (hoten, s);
………
}
~ NhanSu () {delete hoten ; }
}
};
Khi nhập họ tên nhân sự, có thể có họ tên dài ngắn khác nhau. Do vậy ta
không nên cấp phát sẵn ô nhớ chứa độ dài họ tên. Bởi như thế là không cần thiết,
tốn ô nhớ. Ta nên cấp phát bộ nhớ động. Và khi đó các thành phần cùng khởi tạo
và cùng kết thúc ở hàm hủy tử ~ nhansu ( ) và con trỏ hoten sẽ được cấp phát
đúng bằng độ dài của họ tên +1 ô nhớ null. Những thành phần này gọi là có kết
dính thời điểm.
Theo [4] thì mức ghép nối này cũng được đánh giá chất lượng là vẫn tốt.
d. Kết dính thủ tục (procedural cohesion).
Các phần tử trong thành phần được ghép lại trong một dãy điều khiển. các
thành phần tạo có một thứ tự xác định.
Chẳng hạn, khi thiết kế các phần mềm tính toán trong tính lương cơ bản,
tính phụ cấp, tính bảo hiểm.
Hay trong phần tính toán trong phần thiết kế phần mềm xét tuyển sinh Đại
học, đầu tiên điểm thi các môn đã biết và điểm ưu tiên, sau đó sẽ tính điểm khối
đó theo hệ số môn thi và điểm ưu tiên. Một dãy lệnh thực hiện tuần tự như thế
thực hiện để nhằm tính điểm thi cho thi sinh. Phần thiết kế này theo tôi cũng có
sự kết dính thủ tục.
Theo [4] mức dính này được nâng lên một mức cao hơn, được đánh giá là
tốt.
e. Kết dính truyền thông(communicational cohesion)
Tất cả các phần tử của thành phần cùng thao tác trên cùng một dữ liệu vào
và đưa ra cùng 1 dữ liệu ra.
Tôi xin đưa ra ví dụ : Khi thống kê điểm tuyển sinh Đại học ta cần đưa ra
toàn bộ dữ liệu, hay đưa ra người có điểm thủ khoa, điểm trung bình mà các thí
sinh đạt được trong năm nay, lọc ra danh sách các em thi đậu …
Hay ở các lệnh thực hiện các nút thêm, sửa, xóa dữ liệu trong bảng
cap_nhat_ho_so của [8’] đều cùng thao tác trên cùng 1 dữ liệu trong bảng hoso.
f. Kết dính tuần tự (sequential cohesion).
Trong một thành phần, cái ra của thành phần này là cái vào của thành phần
kia
Tôi thấy trong phần mềm quản lý Tin 3B [8’]. Đây là đoạn code đọc file
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim frm As New ChonHoso
frm.MdiParent = Me.MdiParent
frm.Show()
Do
My.Application.DoEvents()
Loop While frm.Visible = True
If frm.Result <> "" Then
Dim S As String = ""
If frm.Result = "*" Then
S = "select maso,hoten from db_hoso"
Else
S = "select maso,hoten from db_hoso where " & frm.Result
End If
If ds.Tables("hoso") IsNot Nothing Then
ds.Tables("hoso").Clear()
End If
QRY(S, ds, "hoso")
MessageBox.Show(ds.Tables("hoso").Rows.Count)
DataGridView1.Columns.Clear()
DataGridView1.AutoGenerateColumns = True
DataGridView1.DataSource = ds.Tables("hoso")
With DataGridView1.Columns("maso")
.HeaderText = "Mã SV"
.Width = 80
.DisplayIndex = 0
End With
With DataGridView1.Columns("hoten")
.HeaderText = "Họ và tên sinh viên"
.Width = 180
.DisplayIndex = 1
End With
DataGridView1.ReadOnly = True
End If
End Sub
Sau khi đọc dữ liệu từ file thì việc xử lý (chỉnh sửa..) dữ liệu đó bắt đầu
được thực hiện.
g. Kết dính chức năng (functional cohesion)
Mỗi phần của thành phần đều là cần thiết để thực hiện 1 chức năng nào nó.
Các thành phần đó là kết quả của phân rã chức năng.
Chẳng hạn khi cập nhật dữ liệu cần có các phần : Đọc dữ liệu về, thêm dữ
liệu, xóa dữ liệu, sửa dữ liệu. Theo tôi, các phần đó kết dính chức năng để tạo
tạo nên chức năng cập nhât dữ liệu.
2. Thế nào là mức ghép nối giữa các module (coupling) ?
Ghép nối chỉ ra mức độ độc lập giữa các đơn vị thành phần (môđun) của
một chương trình. Hệ thống có ghép nối cao sẽ có độ liên kết mạnh giữa các
thành phần, làm chúng phụ thuộc lẫn nhau nhiều hơn. Hệ thống nối ghép lỏng
lẻo làm cho các thành phần trở nên độc lập hay tương đối độc lập với nhau.
Ta có thể vẽ hình đễ dễ hiểu hơn về sự kết dính và sự ghép nối theo [2] như
sau :
Class NhanSu
{
public :
... Void main()
Void nhap() { NhanSu NS
{ ….} [100] ;
} int i=0;
….
NhanSu[i].nhap()
Ghép nối chuẩn là loại ghép nối lỏng lẻo và tốt nhất.
Class HinhChuNhat
{int x,y;
Public:
int DienTich (int &x, int &y)
{ return x*y; }
Void HienThi( HinhChuNhat *hcn, int n)
{
for (int i=0; i< n-1; ++i )
cout <<”dien tich cua hinh chu nhat thu <<i+1 <<”la :”
<< DienTich(hcn[i].x, hcn[i].y)
}
....
Hàm HienThi sẽ truyền tham số cho hàm DienTich theo kiểu tham chiếu.
Với giá trị đó, các câu lệnh ở trong hàm HienThi dược thực hiện và đưa ra kết
quả trong hàm HienThi. và mọi thành phần (câu lệnh) trong hàm DienTich, hàm
HienThi không hề hay biết.
Có thể nói ghép nối dữ liệu được đánh giá là một loại ghép nối rất tốt trong
thiết kế, theo [4]. Tuy nhiên, theo [3] nếu sự ghép nối là sự liên hệ tới một dữ
liệu xác định trong một module khác, không phải bởi một phép truyền tường
minh qua một phép nối chuẩn thì lại là một ghép nối dữ liệu xấu.
c. Ghép nối nhãn (stamp coupling)
Các dữ liệu được giửi đi là những cấu trúc dữ liệu hay toàn bộ một bản ghi.
Sự thay đổi trong cấu trúc dữ liệu sẽ tác động lên mọi module sử dụng nó,
chúng phụ thuộc nhau nhiều hơn.
Tôi thấy một ví vụ ở [8’’], Dữ liệu ở bảng cập nhật phòng bệnh cho phép
đọc dữ liệu từ bảng DanhMucPhongBenh và đồng thời dữ liệu ở của nó mới cập
nhật được giửi qua Bảng DanhMucPhongBenh. Như ở nút sửa của bảng
capnhatphongbenh :
Theo [4] thì mức ghép nối này cũng được đánh giá là loại ghép nối tốt.
d. Ghép nối điều khiển (control coupling)
Việc xảy ra khi các module trao đổi thông tin điều khiển.
Khi tham khảo ví dụ trong [4], tôi đưa ra ví dụ như sau:
Loại này xảy ra khi một thành phần trực tiếp tham chiếu đến hoạt động của
một thành phần khác.. Chẳng hạn ở các ngôn ngữ bậc thấp có sử dụng goto,
lệnh cho phép thực hiện bước nhảy đến một nhãn nhất định trong chương trình
3. Tính hiểu được (Understandability):
Theo [1], tính hiểu được liên quan tới một số đặc trưng sau :
a. Tính kết dính:
Ta có thể hiểu được một thành phần mà không cần tham khảo đến một
thành phần khác. Điều này tùy thuộc sự liên kết chặt chẽ giữa các phần tử của
thành phần. Chẳng hạn, tôi thấy trong đoạn:
chứa. Muốn là tự chứa hoàn toàn thì một thành phần không nên dùng các thành
phần ngoại lai (tức là không nên dùng thư viện ngoài). tuy nhiên, điều này lại
mâu thuẫn với việc dùng lại các thành phần sẵn có. Vì vậy, cần có một sự thõa
hiệp giữa tính dùng lại và mất tính thích nghi được.
Tôi xin đưa ra một ví dụ nổi bật cho tính thích nghi này, đó chính là các
module theo hướng đối tượng (class), như Class Add_new_user trên chẳng hạn.
Việc thiết kế xoay quanh các đối tượng và dùng các thư viện trong sẽ rất phù
hợp cho việc thay đổi, sử dụng lại các class này để các thiết kế này hoàn chỉnh
hơn.
III. CÁC GIẢI PHÁP CHO MỘT THIẾT KẾ TỐT
Theo [1], ta có thể nhận được một thiết kế tốt nếu thực hiện đúng tiến trình
thiết kết phần mềm thông qua việc áp dụng các nguyên lý cơ bản, các phương
pháp luận hệ thống, các công cụ trợ giúp và việc xét duyệt nghiêm túc. Tuy
nhiên, điều đó chưa đủ đảm bảo chắc chắn một thiết kế đã hoàn hảo. Về nguyên
tắc để đảm bảo chất lượng thiết kế cần có một hệ các tiêu chuẩn cho thiết kế.
Xây dựng một hệ thống tiêu chuẩn tốt đã không đơn giản, thì quá trình đảm bảo
thiết kế thực hiện các chuẩn đó càng khó khăn hơn. Thay vào đó, người ta đã đưa
ra các hướng dẫn để hướng thiết kế đạt được một mức độ chất lượng nhất định :
- Hình thành giao diện để rút gọn độ phức tạp của việc
ghép nối giữa các module giữa môi trường bên ngoài cũng như giữa chúng với
nhau.
- Sử dụng lại các phần mềm đã có, trong đó có các mã
nguồn, các mẫu thiết kế …
2. Những nguyên lý thiết kế cần vận dụng.
1) Không rõ ràng tiến trình thiết kế trong một “Cách nhìn hạn hẹp”.
Người thiết kế cần tính đến mọi cách tiếp cận khác nhau dựa trên yêu cầu của
vấn đề đặt ra và khả năng của các nguồn lực đó có được.
2) Thiết kế có thể lần vết trở lại mô hình phân tích hay các bước trước nó.
3) Thiết kế không nên giải quyết vấn đề đã được giải quyết. Nên sử dụng
các mẫu đã gặp để cấu trúc hệ thống.
4) Thiết kế phải rút ngắn được khoảng cách giữa các phần mềm và vấn đề
tồn tại trong thế giới thực.
5) Thiết kế cần thể hiện tính nhất quán và tích hợp.
6) Thiết kế cần được cấu trúc để dễ thay đổi.
7) Thiết kế không phải mã hóa, mã hóa không phải thiết kế.
8) Thiết kế cần được xem xét ngay từ đầu để tối thiểu hóa các lỗi.
9) Thiết kế cần được đánh giá và rà soát chất lượng trong quá trình phát
triễn.
C. TỔNG KẾT
Đề tài đã hoàn thành với việc tổng hợp, phân tích nhiều kết quả của các nhà
nghiên cứu, tìm hiểu về “Đánh giá chất lượng thiết kế phần mềm” và vận dụng,
phân tích vào các ví dụ cụ thể của các thiết kế phần mềm sưu tầm hoặc các đoạn
code tự tôi chế tác.
Qua đề tài, tôi đã học được nhiều điều không những về kiến thức ”Đánh giá
thiết phần mềm có chất lượng” mà còn về khả năng đánh giá, hiểu, vận dụng,
tổng hợp, phân tích. Bởi lẻ đề tài đòi hỏi tôi phải đọc rất nhiều tài liệu lý thuyết
liên quan, hiểu về ngôn ngữ lập trình, về các cách tiếp cận ngôn ngữ lập trình,
hiểu về phần mềm... Và đề tài đã đưa ra được các giải pháp để có thiết kế tốt, để
người làm thiết kế phần mềm có thể ứng dụng vào phần mềm của mình.
Trong vốn khả năng của mình và việc vận dụng, phân tích vào các tài liệu
liên quan đến ”Đánh giá chất lượng thiết kế phần mềm”, nên đề tài vẫn còn cần
nhiều sự đánh giá, góp ý. Tôi hi vọng đề tài sẽ có nhiều nhận được ý kiến đánh
giá, góp ý. Qua đó, tôi thấy được sự vận dụng, tổng hợp, phân tích của mình
đúng sai chỗ nào và để cho trong tương lai đề tài càng hoàn thiện hơn.
Nếu có thời gian thì đề tài này không chỉ dừng lại ở một bài tiểu luận và
tôi sẽ bổ sung thêm ở mục cuối bằng cách đưa ra một phần mềm cụ thể, đánh giá
tốt, xấu và đề ra các giải pháp cụ thể cho thiết kế phần mềm đó được tốt hơn.
Phần bổ sung đó cũng chính là hướng phát triển của đề tài.
- [1] Nguyễn Văn Vỵ, Nguyễn Việt Hà ,”Giáo Trình Kỹ Nghệ Phần
Mềm”- Nhà Xuất Bản Đại Học Quốc Gia Hà Nội , 02/2003
- [2] Ngô Trung Việt, Nguyễn Kim Ánh, ”nhập môn Kỹ Nghệ Phần
Mềm”- Nhà Xuất Bản Khoa Học Và Kỹ Thuật Hà Nội-14/03/2008
- [3] Lê Văn Tường Lân, ”giáo trình Công Nghệ Phần Mềm ”- khoa Công
nghệ thông tin,trường ĐHKH huế, 02/2004.
- [4] Silde bài giảng cho lớp K50CA và K50CB- PGS.TS. Nguyễn Ngọc
Bình, ”Công Nghệ Phần Mềm”- Đại Học Quốc Gia Hà Nội
- [5] Nguyễn Việt Hà, ” bài giảng Kỹ Nghệ Phần Mềm”
- [6] Ian Sommerville, ”Software Engineering”, 6th ed., Addison-Wasley,
2001.
- [7] Trang web về Mô hình chất lượng ISO - 9126
http://www.pcworld.com.vn/articles/quan-ly/tu-van/2004/02/1185833/mo-
hinh-chat-luong-iso-9126/
- [8] Một số phần mềm :
+ [8’] Quản lý Tin 3b trong bài giảng môn lập trình ứng dụng, thầy
Nguyễn Lương Thục, khoa tin học, trường ĐHSP Huế
+ [8’’] Quản lý bệnh nhân của Nguyễn Văn Thọ- Tin 3b , trường
ĐHSP Huế
+ [8’’’] Quản lý nhà sách, Nhóm học tập- Nhóm 1 lớp tin 3b, trường
ĐHSP Huế
- [9] Các tài liệu có liên quan về đánh giá chất lượng và các tài liệu về lập
trình khác.