Professional Documents
Culture Documents
CHƯƠNG 1
MỞ ĐẦU1
1
Chương 1: Mở đầu Trần Đình Quế
2
Chương 1: Mở đầu Trần Đình Quế
3
Chương 1: Mở đầu Trần Đình Quế
1.3 MÔ HÌNH HỆ THỐNG DỰA TRÊN CÁCH TIẾP CẬN HƯỚNG ĐỐI TƯỢNG
1.3.2 UML
Trong môn Công nghệ phần mềm, chúng ta đã làm quen với UML. Phần này trình bày tổng quan
để có cái nhìn đầy đủ hơn 13 kiểu biểu đồ trong UML. Đặc tả UML không nói các biểu đồ này
nên sử dụng ở đâu trong từng phương pháp luận nên chúng ta được phép tự do sử dụng chúng ở
bất cứ lúc nào thấy thích hợp.
• Biểu đồ use case (use case diagram) • Biểu đồ triển khai (Deployment
• Biểu đồ lớp (class diagrams) diagrams)
• Biểu đồ đối tượng (Object diagrams) • Biểu đồ thành phần (Component
• Biểu đồ hoạt đông (Activity diagrams)
diagrams) • Biểu đồ tổng quan tương tác (Interaction
• Biểu đồ máy trạng thái (State overview diagrams)
machine diagrams) • Biểu đồ thời gian (Timing diagrams)
• Biểu đồ truyền thông • Biểu đồ cấu trúc hợp (Composite
(Communication diagrams) structure diagram)
• Biểu đồ dãy (Sequence diagrams)
• Biểu đồ gói (Package diagrams)
4
Chương 1: Mở đầu Trần Đình Quế
5
Chương 1: Mở đầu Trần Đình Quế
• Biểu đồ hoạt đông (Activity diagram): mô hình các tiến trình nghiệp vụ. Một tiến trình
nghiệp vụ là sự kết hợp của các tác vụ nhằm đạt được một mục đích nghiệp vụ nào đó. Ví
dụ, phân phối đơn hàng của khách hàng…
• Biểu đồ máy trạng thái (State machine diagram): mô hình các trạng thái của một đối
tượng.
• Biểu đồ tuần tự (Sequence diagram): cho phép mô hình một cách chính xác cách các
thành phần của hệ thống tương tác với nhau..
• Biểu đồ giao tiếp (Communication diagram): tập trung vào liên kết tương tác. Nó chỉ ra
các liên kết nào cần thiết để truyền thông điệp tương tác giữa các bên tham gia
• Biểu đồ thời gian (Timing diagram): mỗi sự kiện có thông tin về thời gian tương ứng
với nó. Biểu đồ này miêu tả chính xác khi nào sự kiện xảy ra, mất bao lâu để bên tham gia
nhận được sự kiện đó và mất bao lâu để bên nhận sự kiện chuyển trạng thái.
• Biểu đồ tổng quan tương tác (Interaction overview diagram): cung cấp cái nhìn mức
cao về cách mà một số tương tác làm việc với nhau để cài đặt hệ thống.
6
Chương 1: Mở đầu Trần Đình Quế
Ví dụ Đối tượng máy pha cà phê tự động aCoffeeMachine bao gồm các thao tác:
- Hiển thị đồ uống
- Lựa chọn đồ uống.
- Nhận tiền.
- Pha chế đồ uống.
Máy pha cà phê cần biết những gì để có thể thực hiện các thao tác trên:
- Các đồ uống đang có sẵn.
- Giá đồ uống.
- Công thức pha chế đồ uống.
Như vậy ta có thể biểu diễn đối tượng máy pha cà phê như sau:
aCoffeeMachine
drinkPrices
availableDrinks
drinkRecipes
displayDrinks()
selectDrink()
dispenseDrink()
acceptMoney()
1.4.2 Lớp
Một lớp đóng gói các đặc điểm chung của một nhóm các đối tượng. Các nhà phát triển hướng đối
tượng sử dụng các lớp để mô tả các thành phần mà các dạng đối tượng cụ thể sẽ có. Không có
lớp, ta sẽ phải thêm các thành phần này vào từng đối tượng riêng biệt. Biểu diễn lớp trong UML
tương tự như biểu diễn đối tượng nhưng tên lớp không gạch chân.
7
Chương 1: Mở đầu Trần Đình Quế
khả năng truy cập của chúng bằng cách sử dụng các phương thức set, get cho mỗi trường để có
thể truy cập tới thuộc tính.
public class Employee {
protected int employeeID;
protected String firstName;
protected String lastName;
public int getEmployeeID() {
return employeeID;
}
public void setEmployeeID(int id) {
employeeID = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String name) {
firstName = name;
}
public String getLastName() {
return lastName;
}
public void setLastName(String name) {
lastName = name;
}
}
Lợi ích của việc đóng gói
• Đóng gói an toàn
• Đóng gói làm đơn giản hóa việc chuyển đổi một lớp đang tồn tại thành một lớp được
dùng để tạo các đối tượng phân tán (từ xa). Đối tượng phân tán thường nằm ở máy chủ,
các phương thức của nó có thể được gọi bởi các ứng dụng nằm trên các máy khác (nói
cách khác là có thể được gọi thông qua mạng). Do đó, các trường thuộc đối tượng đó
không thể được gọi trực tiếp như với đối tượng cục bộ. Tuy nhiên, nếu định nghĩa các
phương thức set và get, ta có thể làm được điều này.
• Ngoài ra, việc sử dụng các phương thức set và get sẽ cô lập chúng ta khỏi những thay đổi
trong cài đặt một tính chất. Ví dụ, có thể đổi employeeID từ kiểu int sang kiểu String mà
không ảnh hưởng tới các lớp khác, miễn là chúng ta thực hiện việc chuyển đổi thích hợp
trong các phương thức set và get.
Đóng gói ẩn giấu việc vài đặt chi tiết
public class Employee {
protected String employeeID;
protected String firstName;
protected String lastName;
public int getEmployeeID() {
return Integer.parseInt(employeeID);
}
public void setEmployeeID(int id) {
employeeID = Integer.toString(id);
8
Chương 1: Mở đầu Trần Đình Quế
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String name) {
firstName = name;
}
public String getLastName() {
return lastName;
}
public void setLastName(String name) {
lastName = name;
}
}
Mặc dù, việc cài đặt thuộc tính employeeID bị thay đổi, nhưng các lớp khác khi đọc và sửa đổi
thuộc tính này sẽ không nhìn thấy bất kỳ thay đổi nào trong hành vi của nó, vì việc thay đổi trong
cài đặt được che giấu bởi các phương thức set và get. Đóng gói các thuộc tính của lớp cho phép
định nghĩa các giá trị dẫn xuất có khả năng truy cập. Ví dụ, bạn có thể định nghĩa phương thức
getFullName() trong lớp Employee để trả về họ tên đầy đủ dưới dạng một chuỗi đơn:
public String getFullName() {
Return firstName + “ “ + lastName;
}
Tất nhiên, có thể lấy giá trị dẫn xuất mà không cần tạo phương thức get, nhưng thường sẽ tạo ra
các đoạn mã trùng nhau khi dẫn xuất giá trị. Ví dụ, để dẫn xuất tên đầy đủ ở một số vị trí trong
ứng dụng, bạn phải copy đoạn mã (firstName + “ “ + lastName) vào các vị trí đó và
nếu thay đổi cài đặt, bạn phải thay đổi từng vị trí như khi bạn muốn có thêm middleName.
Nhưng khi sử dụng phương thức getFullName() thì bạn chỉ cần thay đổi ở một vị trí trong
mã nguồn mà thôi.
khoảng không gian…nhưng liên kết sẽ mất khi xe trả một vị khách nào đó đến nơi yêu
cầu, vị khách đó sẽ không còn liên kết với các đối tượng xe và người lái xe nữa.
• Aggregation: nghĩa là đặt các đối tượng có liên kết với nhau cùng nhau để tạo ra đổi
tượng lớn hơn. Ví dụ, máy tính được tạo bởi các bộ phận màn hình, ổ cứng, bàn
phím…Aggregation thường có dạng phân cấp bộ phận-toàn thể (part-whole).
Aggregation ám chỉ sự phụ thuộc giữa bộ phận và toàn thể, ví dụ, màn hình vẫn là màn
hình nếu lấy nó ra khỏi máy tính, nhưng máy tính sẽ mất tác dụng nếu thiếu màn hình.
Như đã nói ở trên, thật khó để phân biệt giữa association và aggregation. Tuy nhiên, có thể đặt
câu hỏi “Điều gì sẽ xảy ra nếu bỏ đi một trong các đối tượng?” để xác định quan hệ đó là
association hay aggregation. Nhưng không phải là lúc nào nó cũng giải quyết được vấn đề mà cần
phải suy nghĩ thường xuyên và cần có kinh nghiệm. Ta thường phải chọn lựa giữa association và
aggregation, vì lựa chọn đó có thể ảnh hưởng đến cách ta thiết kế phần mềm.
Ví dụ “xử lý hóa đơn”
Liên kết (Association): Quan hệ Association thường được miêu tả giống như quan hệ tham chiếu
(reference), trong đó một đối tượng nắm giữ một tham chiếu đến đối tượng khác.
package relation;
10
Chương 1: Mở đầu Trần Đình Quế
Đây là quan hệ dễ cài đặt nhất, trong UML nó được biểu diễn là một đường thẳng nối giữa 2 lớp.
Chiều mũi tên nói lên rằng ta gọi đối tượng Customer từ đối tượng Order nhưng không gọi Order
từ Customer.
Tập hợp (Aggregation)
Quan hệ giữa lớp OrderList và lớp Order là Aggregation. Nghĩa là danh sách OrderList
bao gồm nhiều Order nhưng các Order có đời sống riêng của nó và không cần phải là một
bộ phận của danh sách OrderList cụ thể.
package relation;
import java.util.Vector;
import aggregation.Order;
11
Chương 1: Mở đầu Trần Đình Quế
Aggregation được biểu diễn trong UML bởi một đường thẳng có hình quả trám rỗng ở 1 đầu.
Điều này xác định không có quan hệ sở hữu trong quan hệ này và các thể hiện của lớp được kết
hợp sẽ được quản lý bên ngoài lớp đang kết hợp.
Hợp thành, cấu thành (Composition)
Quan hệ giữa Order và OrderLine là Composition. Các OrderLine của một Order đều
thuộc về Order và không có ý nghĩa bên ngoài Order đó. Order có trách nhiệm hoàn toàn
trong việc tạo, quản lý, và xóa bất kỳ OrderLine nào trong Order đó. Biểu diễn trong UML
là đường thẳng một đầu có hình quả trám màu đen.
package relation;
public class Order {
private Customer _customer;
private OrderLine[] _orderLine;
private Currency _total;
aggregation.OrderList _unnamed_OrderList_;
1.6.2 Kế thừa
Kế thừa cho phép một lớp lấy lại một số đặc điểm, thuộc tính từ lớp cha và sau đó thêm vào một
số đặc trưng riêng của nó. Kế thừa cho phép ta nhóm một số lớp thành một lớp tổng quát hơn để
có thể đưa ra các đối tượng rộng hơn về thế giới mà ta đang sống.
Thiết kế kiến trúc phân cấp lớp
Ví dụ, ta muốn mô hình các bộ sưu tập để lưu giữ các đối tượng cho sử dụng về sau này. Sau khi
phân tích, ta thấy có 4 kiểu bộ sưu tập như sau:
12
Chương 1: Mở đầu Trần Đình Quế
• List: lưu giữ các đối tượng theo thứ tự mà nó được đưa vào.
• Bag: lưu các đối tượng nhưng không theo thứ tự.
• LinkedList: lưu các đối tượng theo thứ tự bằng cách cài đặt một chuỗi các đối tượng
trong đó mỗi đối tượng chỉ tới một đối tượng khác trong chuỗi. Danh sách liên kết cho
phép cập nhật dễ dàng, nhưng truy cập chậm vì ta phải duyệt toàn bộ danh sách.
• ArrayList: lưu các đối tượng theo thứ tự sử dụng như là một mảng, nghĩa là một chuỗi
các ô nhớ liên tiếp. Mảng cho phép truy cập nhanh nhưng cập nhật chậm vì ta có thể phải
dịch các phần tử hoặc tạo một mảng mới mỗi khi cập nhật.
Làm thế nào thiết kế kiến trúc phân cấp kiểu kế thừa? Điểm mấu chốt là xem xét sự tương
đồng giữa các khái niệm với nhau. Rõ ràng, chúng đều là các bộ sưu tập, vì vậy lớp
Collection sẽ đưa lên đầu. Trong 4 bộ sưu tập trên, chỉ có Bag là không lưu các đối tượng
theo thứ tự, còn lại đều lưu đối tượng theo thứ tự. Do đó, ta đặt Bag trực tiếp ngay bên dưới
Collection trong một nhánh riêng. Ta thấy, List không có ràng buộc gì về cài đặt bên
trong, trong khi LinkedList và ArrayList thì có. Vì vậy, List sẽ là lớp cha của
LinkedList và ArrayList. Ta có bản thiết kế phân cấp lớp như sau:
13
Chương 1: Mở đầu Trần Đình Quế
Đặt các message này vào lớp nào? Contains() có thể dùng đối với mọi bộ sưu tập, vì vậy
đặt nó trong Collection. ElementAt(: int) lấy đối tượng ở vị trí xác định nên phải đặt
trong List, để tránh sự lặp lại nếu để trong ArrayList và LinkedList.
NumberOfElement() có thể dùng với mọi bộ sưu tập nên để nó trong Collection. Ta có
bản thiết kế sau đây:
14
Chương 1: Mở đầu Trần Đình Quế
15
Chương 1: Mở đầu Trần Đình Quế
16
Chương 1: Mở đầu Trần Đình Quế
Employee đóng gói các thuộc tính và một tập các thao tác của nhân viên được sử dụng
trong toàn bộ công ty. Những người ưa chuộng hướng đối tượng là những người muốn tạo
ra nơi chứa tài nguyên dùng lại để chứa các lớp hơn là các hàm.
• Dùng lại các lớp trong tất cả các hệ thống: một bộ phận trong phần mềm cũng tương tự
như một bộ phận trong phần cứng. Các thành phần trong phần mềm được thiết kế để có
thể dùng lại trong nhiều ngữ cảnh, được đóng gói chặt chẽ (bên yêu cầu không biết công
việc bên trong là gì), đi cùng với phong cách chuẩn của interface, và được cung cấp sẵn từ
bên thứ 3, thường là phải trả chi phí. Mỗi ngôn ngữ lập trình hướng đối tượng có một
khuôn mẫu các thành phần trong phần mềm, ví dụ JavaBeans, EJB, .NET
• Các thư viện hàm: các hàm có liên quan, có chất lượng tốt có thể được nhóm lại thành
một thư viện, vì vậy chúng luôn sẵn có. Ví dụ thư viện stdio, bắt nguồn từ các hệ thống
Unix, cung cấp khả năng I/O cho các lập trình viên C. Các thư viện hàm được dùng trong
cả việc phát triển phần mềm truyền thống cũng như phát triển phần mềm hướng đối
tượng. Các thư viện được thiết kế tốt đôi khi được chuẩn hóa bởi các tổ chức như ISO hay
ANSI. Các thư viện hàm có thể xuất phát từ bên trong công ty, sử dụng miễn phí hoặc
bán để kiếm lời.
• Các thư viện lớp: là một sự phát triển của các thư viện chức năng, thường là các lớp hoàn
chỉnh chứ không đơn thuần là các hàm. Viết một thư viện lớp đòi hỏi có nhiều kinh
nghiệm. Ví dụ thư viện J2EE, cung cấp mã nguồn cho tất cả các kiểu dùng lại được liệt kê
ở trên.
• Mẫu thiết kế: một mẫu thiết kế (design pattern) là một sự miêu tả cách tạo ra các phần
của hệ thống HĐT một cách hiệu quả. Các bản mẫu cũng được áp dụng trong các lĩnh vực
khác như kiến trúc hệ thống. Mỗi mẫu là một miêu tả ngắn, chi tiết, cho biết khi nào dùng
nó và code minh họa. Thiết kế các mẫu đòi hỏi người có nhiều kinh nghiệm, nhưng không
bằng việc tạo ra thư viện lớp.
• Framework: là một cấu trúc đã có sẵn để bạn đưa code vào. Trong trường hợp HĐT, một
framework bao gồm một số lớp được viết trước, cùng với tài liệu miêu tả hướng dẫn lập
trình viên các quy tắc phải tuân theo. Ví dụ EJB framework – bao gồm thư viện J2EE và
tài liệu đặc tả, dài hàng trăm trang – chỉ ra cách để lập trình viên viết được các thành phần
có khả năng dùng lại, và cách để các bên thứ 3 cài đặt máy chủ ứng dụng Java. Phần lớn
các framework được thiết kế bởi các chuyên gia cao cấp.
17
Chương 1: Mở đầu Trần Đình Quế
chuyên gia trong lĩnh vực thú vị này. Các chương tiếp theo sẽ giúp sinh viên hiểu rõ hơn những
vấn đề này.
BÀI TẬP
1. Sinh viên tìm hiểu và khảo sát các hệ quản lý học tập theo tín chỉ và sau đó đề xuất các yêu
cầu của hệ thống này. Liệt kê các actor cùng các use case có thể có cho hệ thống.
2. Hãy chọn ra các lớp từ hệ quản lý học tập theo tín chỉ trong câu 1 và chỉ ra các quan hệ giữa
chúng
3. Hãy thêm các thuộc tính và các phương thức vào các lớp chọn được
4. Hãy giải thích lý do chọn lựa các mức độ truy nhập các thuộc tính trên
5. Hãy giải thích lý do gán phương thức vào các lớp
6. Sinh viên có thể tham khảo các tài liệu trên mạng để viết ví dụ một mẫu thiết kế. Chú ý khi
trình bày cần ghi rõ địa chỉ link của tài liệu
18
Chương 1: Mở đầu Trần Đình Quế
19