Nguyên lý thiết kế
hướng đối tượng
Lập trình hướng đối tượng
Nguyên lý thiết kế hướng
đối tượng 2
Bob Tarr
Nguyên tắc số 1
Giảm thiểu khả năng truy nhập
tới lớp và các thành viên
Nguyên lý thiết kế hướng
đối tượng 3
Bob Tarr
"Trừu tượng hóa" nghĩa là gì?
Tony Hoare: “trừu tượng hóa xuất phát từ một cách nhìn nhận
những đặc điểm tương đồng giữa một số đối tượng, tình thế, hoặc
quy trình nhất định trong thế giới thực, và quyết định tập trung vào
những điểm tương đồng này và nhất thời lờ đi các điểm khác biệt.”
Grady Booch: “Một trừu tượng hóa kí hiệu các đặc điểm cốt lõi của
một đối tượng mà các đặc điểm này phân biệt nó với tất cả các loại
đối tượng khác, cho ta các ranh giới được xác định rõ ràng. Tất cả
được xét một cách tương đối trong góc nhìn của người quan sát.”
Trừu tượng hóa là một trong những phương pháp nền tảng để đối
phó với sự phức tạp
Một trừu tượng hóa tập trung vào hình ảnh bên ngoài của một đối
tượng và tách hành vi của đối tượng đó ra khỏi cài đặt của nó.
Nguyên lý thiết kế hướng
đối tượng 4
}
public double setSpeed(double newSpeed) {
speed = …
}
Nguyên lý thiết kế hướng
đối tượng 6
Bob Tarr
Che dấu thông tin ở Java
Ta có thể quy định các ràng buộc về giá trị
public void setSpeed(double newSpeed) {
if (newSpeed < 0) {
sendErrorMessage( );
newSpeed = Math.abs(newSpeed);
}
speed = newSpeed;
}
Nếu các client được truy cập trực tiếp đến thành viên dữ liệu thì
từng client phải chịu trách nhiệm kiểm tra ràng buộc
Nguyên lý thiết kế hướng
đối tượng 7
Bob Tarr
Che dấu thông tin ở Java
Ta có thể thay đổi biểu diễn dữ liệu bên trong lớp đối
tượng mà không phải sửa giao diện
// Now using metric units (kph, not mph)
public void setSpeedInMPH(double newSpeed) {
speedInKPH = convert(newSpeed);
dựng bằng cách tạo một đối tượng có thành phần là các đối tượng
khác
Chức năng mới được tạo bằng cách sử dụng chức năng của một
trong các đối tượng thành phần
Composition có thể là chứa
Tham chiếu
Giá trị
C++ cho phép chứa giá trị đối tượng hoặc chứa tham chiếu đối
tượng
Java chỉ cho phép chứa tham chiếu đối tượng.
Nguyên lý thiết kế hướng
đối tượng 11
Bob Tarr
Ưu/nhược điểm của Composition
Ưu điểm:
Lớp chứa chỉ có thể truy nhập tới các đối tượng thành phần qua
giao diện của các đối tượng đó.
Tái sử dụng kiểu "hộp đen", do chi tiết cài đặt của các đối tượng
thành phần không lộ ra ngoài
Tính đóng gói cao
tường minh các thuộc tính và phương thức
chung
Lớp chuyên hóa (subclass) mở rộng cài đặt với
các thuộc tính và phương thức bổ sung
Nguyên lý thiết kế hướng
đối tượng 14
Bob Tarr
Ưu nhược điểm của thừa kế
Ưu điểm:
Dễ dàng cài lớp mới, do phần lớn đã được thừa kế
Dễ sửa hoặc mở rộng cài đặt được tái sử dụng
Nhược điểm
Phá vỡ tính đóng gói, do nó để cho lớp con biết về chi tiết cài đặt
của lớp cha
Tái sử dụng kiểu "hộp trắng"
Có thể phải sửa lớp con nếu cài đặt của lớp cha có thay đổi.
Tại thời gian chạy, không thể thay đổi cài đặt đã được thừa kế từ
các lớp cha
Nguyên lý thiết kế hướng
đối tượng 15
Bob Tarr
Ví dụ Inheritance & Compostion
Ví dụ lấy từ cuốn Effective Java của Joshua Bloch.
InstrumentedHashSet s = new InstrumentedHashSet();
s.addAll(Arrays.asList(new String[] {"Snap","Crackle","Pop"}));
System.out.println(s.getAddCount());
}
Nguyên lý thiết kế hướng
đối tượng 17
Bob Tarr
Ví dụ Inheritance & Compostion
Kết quả là 6 thay vì 3 như trông đợi. Tại sao?
Cài đặt bên trong của addAll() trong lớp cha
HashSet gọi phương thức add()
Tại add() của InstrumentedHashSet, ta cộng 3 vào
addCount
Gọi addAll() của HashSet, với mỗi phần tử, phương
thức addAll() này lại gọi add() – bản định nghĩa lại
của IntrumentedHashSet.
Kết quả: mỗi phần tử bổ sung được đếm 2 lần
Nguyên lý thiết kế hướng
đối tượng 18
Bob Tarr
Ví dụ Inheritance & Compostion
Có vài cách sửa, nhưng hãy ghi nhận điểm yếu của lớp
con IntrumentedHashSet: chi tiết cài đặt của lớp cha ảnh
hưởng tới hoạt động của lớp con
public void clear() { s.clear(); }
public boolean contains(Object o) { return s.contains(o); }
public boolean isEmpty() { return s.isEmpty(); }
public int size() { return s.size(); }
public Iterator iterator() { return s.iterator(); }
public boolean remove(Object o) { return s.remove(o); }
public Object[] toArray() { return s.toArray(); }
public boolean equals(Object o) { return s.equals(o); }
public String toString() { return s.toString(); }
Nguyên lý thiết kế hướng
đối tượng 20
Bob Tarr
Ví dụ Inheritance & Compostion
Một vài điểm cần lưu ý về InstrumentedSet :
Lớp này là một Set
Có một constructor có tham số là một Set
Đối tượng Set nằm trong lớp có thể là một đối tượng thuộc bất
cứ lớp nào cài đặt interface Set (có thể không phải HashSet)
Lớp này rất linh động và có thể bọc ra ngoài một đối tượng Set
bất kì
Ví dụ:
int capacity = 7;
float loadFactor = .66f;
Set s2 = new InstrumentedSet(new HashSet(capacity, loadFactor));
"Là một loại đặc biệt" chứ
không phải "là một vai trò" của lớp cha.
Sai. Passenger hay Agent đều là
các vai trò mà một người có thể giữ
Không biến đổi
Sai. Một người có thể lúc này là một passenger, lúc khác lại là agent
Mở rộng chứ không định nghĩa lại hoặc xóa bỏ
Đúng
Không mở rộng một lớp tiện ích
Đúng
Trong ngữ cảnh bài toán, chuyên biệt hóa một vai trò, giao tác, hoặc
thiết bị.
Sai. Một Person không phải là một vai trò, giao tác, hay thiết bị
Nguyên lý thiết kế hướng
đối tượng 24
Bob Tarr
Ví dụ 1 - Composition
Nguyên lý thiết kế hướng
đối tượng 25
Bob Tarr
Ví dụ 2. Inheritance/Composition