Tải bản đầy đủ (.ppt) (55 trang)

Tài liệu NGUYÊN LÝ THIẾT KẾ HƯỚNG ĐÔI TƯỢNG - LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG doc

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (603.92 KB, 55 trang )

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


Bob Tarr
Đóng gói - encapsulation

Grady Booch: "Đóng gói là để chia tách giữa giao diện
cam kết của một trừu tượng hóa và cài đặt của nó.

Craig Larman: "Đóng gói là một cơ chế được dùng để
che dữ liệu, cấu trúc bên trong, và chi tiết cài đặt của
một đối tượng. Mọi tương tác với đối tượng được thực
hiện qua một giao diện công khai của các thao tác"

Các lớp đối tượng không nên để mở các chi tiết cài đặt
nội bộ của mình
Nguyên lý thiết kế hướng
đối tượng 5
Bob Tarr
Che dấu thông tin ở Java

Sử dụng các thành viên private và các hàm đọc (get) và ghi (set)
mỗi khi có thể.

Ví dụ:

Thay thế
public double speed;

bằng
private double speed;
public double getSpeed() {
return speed;

}
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);

}
public void setSpeedInKPH(double newSpeed) {
speedInKPH = newSpeed;
}
Nguyên lý thiết kế hướng
đối tượng 8
Bob Tarr
Che dấu thông tin ở Java

Ta có thể thực hiện các hiệu ứng phụ tùy ý
public void setSpeed(double newSpeed) {
speed = newSpeed;
notifyObservers();
}

Nếu các client của một lớp truy nhập trực tiếp
dữ liệu của mình, mỗi client sẽ phải chịu trách
nhiệm chạy hiệu ứng phụ
Nguyên lý thiết kế hướng
đối tượng 9
Bob Tarr
Nguyên tắc số 2
Ưu tiên sử dụng Composition hơn
Inheritance
Nguyên lý thiết kế hướng
đối tượng 10
Bob Tarr
Composition

Phương pháp tái sử dụng mà trong đó chức năng mới được xây

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 phụ thuộc về cài đặt hơn

Mỗi lớp chỉ chú trọng vào một tác vụ

Quan hệ composition có thể được xác định một cách động trong
thời gian chạy qua việc đối tượng nhận tham chiếu tới các đối
tượng khác
Nguyên lý thiết kế hướng
đối tượng 12
Bob Tarr
Ưu/nhược điểm của Composition

Nhược điểm

Kết quả là hệ thống có xu hướng chứa
nhiều đối tượng hơn

Các giao diện phải được định nghĩa cẩn
thận để sử dụng nhiều đối tượng khác
nhau trong vai trò các khối cấu thành
Nguyên lý thiết kế hướng
đối tượng 13
Bob Tarr
Thừa kế

Phương pháp tái sử dụng mà trong đó chức
năng mới được xây dựng bằng cách mở rộng
cài đặt của một đối tượng có sẵn

Lớp tổng quát (superclass) liệt kê một cách

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.

Ta cần một dạng HashSet (tập hợp được cài bằng bảng băm) có chức
năng lưu lại số lần chèn thêm phần tử. Ta tạo lớp con của HashSet:
public class InstrumentedHashSet extends HashSet {
// The number of attempted element insertions
private int addCount = 0;
public InstrumentedHashSet(Collection c) {super(c);}
public InstrumentedHashSet(int initCap, float loadFactor) {
super(initCap, loadFactor);
}
Nguyên lý thiết kế hướng
đối tượng 16
Bob Tarr
public class InstrumentedHashSet extends HashSet {
// The number of attempted element insertions
private int addCount = 0;
public InstrumentedHashSet(Collection c) {super(c);}
public InstrumentedHashSet(int initCap, float loadFactor) {
super(initCap, loadFactor);
}
public boolean add(Object o) {
addCount++;
return super.add(o);
}
public boolean addAll(Collection c) {
addCount += c.size();
return super.addAll(c);
}
public int getAddCount() { return addCount; }
}
public static void main(String[] args) {

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


Cách sửa tốt nhất: sử dụng composition.

Viết lớp IntrumentedSet chứa một đối tượng Set

Lớp này lặp lại interface Set, nhưng tất cả các thao tác tập hợp
sẽ được chuyển tới cho đối tượng Set chứa trong
IntrumentedSet

IntrumentedSet được gọi là một lớp bọc ngoài (wrapper class),
nó bọc ra ngoài một đối tượng Set

Đây là ví dụ về đại diện ủy quyền qua việc sử dụng composition
Nguyên lý thiết kế hướng
đối tượng 19
Bob Tarr
public class InstrumentedSet implements Set {
private final Set s;
private int addCount = 0;
public InstrumentedSet(Set s) {this.s = s;}
public boolean add(Object o) {
addCount++;
return s.add(o);
}
public boolean addAll(Collection c) {
addCount += c.size();
return s.addAll(c);
}
public int getAddCount() {return addCount;}
// Forwarding methods (the rest of the Set interface methods)

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));

List list = new ArrayList();
Set s1 = new InstrumentedSet(new TreeSet(list));
Nguyên lý thiết kế hướng
đối tượng 21
Bob Tarr
Quy tắc Coad
Chỉ sử dụng thừa kế khi tất cả các tiêu chí sau đều được thỏa mãn:

Lớp con "là một loại đặc biệt" chứ không phải "là một vai trò" của
lớp cha.

Đối tượng của lớp con không bao giờ cần trở thành một đối tượng
của một lớp khác

Lớp con mở rộng, chứ không định nghĩa lại hoặc xóa bỏ, các trách
nhiệm của lớp cha

Lớp con không mở rộng khả năng của một lớp chỉ là lớp tiện ích

Đối với một lớp trong ngữ cảnh thực của bài toán, lớp con chuyên
biệt hóa một vai trò, giao tác, hoặc thiết bị.
Nguyên lý thiết kế hướng
đối tượng 22
Bob Tarr
Ví dụ 1
Nguyên lý thiết kế hướng
đối tượng 23
Bob Tarr
Ví dụ 1


"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

×