Chào các bạn, mình có đọc bài Design Pattern Strategy của anh Hải thấy khá dễ hiểu và bổ ích, quan trọng hơn là có thể áp dụng cho project đang mở rộng của mình. Tuy nhiên mình gặp một vấn đề khó giải quyết khi thử áp dụng nó, mong các bạn góp ý giúp. Mình sẽ mô tả luôn dựa trên ví dụ trong bài viết:
Theo bài viết về Strategy, ta có class Vehicle là class cơ sở, Các class con là StreetRacer
, Helicopter
, Jet
kế thừa từ Vehicle. Dể tránh sự phụ thuộc của các class con vào class cha khi viết method go(), ta tạo ra interface GoAlgorithm chứa phương thức go() và trong Vehicle sẽ có 1 đối tượng GoAlgorithm và có setter để các class con set Algorithm nào cần thiết, các class “Strategy” là GoByDrivingAlgorithm, GoByFlying, GoByFlyingFast impliment GoAlgorithm. bây giờ đã tách biệt khi các class con chỉ cần set GoAlgorithm tương ứng cần dùng. Ok đến đây mình chưa thấy vấn đề gì cả.
Tuy nhiên khi triển khai, class Jet sẽ dùng đối tượng của GoByFlyingFast để thực hiện method go() tuy nhiên để thực hiện được method go() này trong project của mình, nó lại cần dữ liệu từ chính class Jet. Như vậy class GoByFlyingFast hiện tại đang phụ thuộc vào class Jet, và cần có thông tin nào đó hoặc method nào đó của Jet để hỗ trợ cho method go() mà GoByFlyingFast đang thực hiện.
Để giải quyết cái này mình phải truyền this (object Jet) vào GoByFlyingFast khi khởi tạo:
class Jet extends Vehicle {
public Jet() {
setGoAlgorithm(new GoByFlyingFast(this));
}
}
Tuy nhiên tiếp theo mình phải thực hiện 1 trong 2 cách để GoByFlyingFast có thể dùng được các thuộc tính và phương thức của Jet:
- C1: Các thuộc tính của của Jet mà GoByFlyingFast dùng sẽ phải có setter, getter, các method hỗ trợ cho go() cũng phải public để GoByFlyingFast dùng. => Không ổn vì phá vỡ class Jet mất rồi.
- C2: Đưa các thuộc tính hoặc method hỗ trợ cho go() của Jet vào trong GoByFlyingFast => Cái này cũng không ổn vì vừa phá vỡ class Jet lại làm cho Jet bị thừa thãi.