Câu hỏi này liên quan đến việc sử dụng mẫu Trình trang trí để thêm ít chức năng cho các đối tượng của các lớp lớn.
Theo mô hình Trang trí cổ điển, vui lòng xem xét cấu trúc lớp sau:
Ví dụ, hãy tưởng tượng điều này xảy ra trong một trò chơi. Trường hợp ConcreteCharacterDecorator
có nghĩa là để thêm ít chức năng cho ConcreteCharacter
họ đang 'gói'.
Chẳng hạn, methodA()
trả về một int
giá trị đại diện cho thiệt hại mà nhân vật gây ra cho kẻ thù. Đơn ConcreteCharacterDecorator
giản chỉ cần thêm vào giá trị này. Vì vậy, nó chỉ cần thêm mã vào methodA()
. Các chức năng của methodB()
vẫn giữ nguyên.
ConcreteCharacterDecorator
sẽ trông như thế này:
class ConcreteCharacterDecorator extends AbstractCharacterDecorator{
ConcreteCharacter character;
public ConcreteCharacterDecorator(ConcreteCharacter character){
this.character = character;
}
public int methodA(){
return 10 + character.methodA();
}
public int methodB(){
character.methodB(); // simply delegate to the wrapped object.
}
}
Điều này không có vấn đề với các lớp nhỏ chứa hai phương thức.
Nhưng nếu AbstractCharacter
xác định 15 phương thức thì sao? ConcreteCharacterDecorator
sẽ phải thực hiện tất cả chúng, mặc dù nó chỉ có nghĩa là thêm ít chức năng.
Tôi sẽ kết thúc với một lớp chứa một phương thức có thêm một ít chức năng và 14 phương thức khác chỉ đơn giản là ủy thác cho đối tượng bên trong.
Nó sẽ trông như vậy:
class ConcreteCharacterDecorator extends AbstractCharacterDecorator{
ConcreteCharacter character;
public ConcreteCharacterDecorator(ConcreteCharacter character){
this.character = character;
}
public int methodA(){
return 10 + character.methodA();
}
public int methodB(){
character.methodB(); // simply delegate to the wrapped object.
}
public int methodC(){
character.methodC(); // simply delegate to the wrapped object.
}
public int methodD(){
character.methodD(); // simply delegate to the wrapped object.
}
public int methodE(){
character.methodE(); // simply delegate to the wrapped object.
}
public int methodF(){
character.methodF(); // simply delegate to the wrapped object.
}
public int methodG(){
character.methodG(); // simply delegate to the wrapped object.
}
public int methodH(){
character.methodH(); // simply delegate to the wrapped object.
}
public int methodI(){
character.methodI(); // simply delegate to the wrapped object.
}
public int methodJ(){
character.methodJ(); // simply delegate to the wrapped object.
}
public int methodK(){
character.methodK(); // simply delegate to the wrapped object.
}
public int methodL(){
character.methodL(); // simply delegate to the wrapped object.
}
public int methodM(){
character.methodM(); // simply delegate to the wrapped object.
}
public int methodN(){
character.methodN(); // simply delegate to the wrapped object.
}
public int methodO(){
character.methodO(); // simply delegate to the wrapped object.
}
}
Rõ ràng, rất xấu xí.
Tôi có lẽ không phải là người đầu tiên gặp phải vấn đề này với Người trang trí. Làm thế nào tôi có thể tránh điều này?
AbstractCharacterDelegator
'chính quy' (vì tất cả các phương thức 'thông thường' trong Java là ảo theo mặc định - có nghĩa là chúng có thể bị ghi đè bằng cách kế thừa các lớp con)? Và có thực hiện chúng chỉ đơn giản là ủy thác cho đối tượng bên trong - và nếu tôi muốn thay đổi điều đó, chỉ cần ghi đè chúng?