2013-08-16 27 views
5

Tôi cần trợ giúp để hiểu khớp nối lỏng lẻo. Làm thế nào để thiết kế một lớp sử dụng thành phần để được ghép lỏng lẻo, khi một đối tượng con cần giao tiếp với đối tượng cha mẹ của chúng? Hãy để tôi đưa ra một ví dụ:Khớp nối lỏng lẻo trong bố cục

Chúng tôi có điều này:

class A { 
    private: 
     B b; 
    public: 
     void foo(); 
}; 

Làm thế nào để đối tượng B gọi hàm foo() từ container lớp A? Câu trả lời rõ ràng là "chỉ cần vượt qua một con trỏ từ A đến b", nhưng điều này là khớp nối chặt chẽ, và một thiết kế không linh hoạt.

Bạn có thể vui lòng cho tôi giải pháp đơn giản cho vấn đề này (trong C++ hoặc Java tốt hơn) hoặc cung cấp các kỹ thuật thiết kế để giải quyết các vấn đề này?

Ví dụ thực tế đời sống của tôi xuất phát từ việc phát triển công cụ trò chơi cho JRPG. Tôi có lớp này:

class StateMachine 
{ 
    private: 
     std::map<std::string, State*> states; 
     State* curState; 
    public: 
     StateMachine(); 
     ~StateMachine(); 
     void Update(); 
     void Render(); 
     void ChangeCurState(const std::string& stateName); 
     void AddState(const std::string& stateName, State* state); 
}; 

Trong mỗi vòng lặp trò chơi Update() của StateMachine được gọi, trong đó kêu gọi các Update() chức năng của curState. Tôi muốn thực hiện curState có thể gọi ChangeCurState từ lớp StateMachine nhưng có khớp nối lỏng lẻo.

+0

Chúng vẫn được ghép nối vì A chứa B. – doctorlove

+0

Tạo thành A quan sát. Biến B thành Observer. –

Trả lời

6

Bạn có thể tách riêng bằng cách sử dụng giao diện.

Tạo giao diện F triển khai phương thức foo() và chuyển giá trị này vào B. Hãy thực hiện F. Bây giờ b có thể gọi foo() trên F mà không biết hoặc thậm chí chăm sóc nó được thực hiện bởi A.

2

Một cách để giảm khớp nối trong tình huống này là xác định giao diện cho các đối tượng sẽ được sử dụng trong bố cục. Điều này đảm bảo rằng bất kỳ thay đổi nào đối với việc triển khai của chúng sẽ không phá vỡ bất kỳ điều gì nếu chúng duy trì giao diện mà bạn đã xác định. Nếu bạn phụ thuộc vào các giao diện cho bố cục, bạn sẽ thấy rằng bạn luôn có thể thay đổi các triển khai của mình mà không phá vỡ các lớp khác của bạn.

0

Nếu A sử dụng B thì bạn có thể sử dụng nó bên trong. Vấn đề phát sinh khi B cần A hoạt động đúng, sau đó cả hai đối tượng được ghép nối. Thay vào đó, bạn nên thử chỉ truyền một số giá trị hoặc tham chiếu đến B chứ không phải toàn bộ đối tượng.

Tái cấu trúc mã của bạn nếu bạn hoàn toàn cần toàn bộ đối tượng A trong B.

0

Có lẽ một cái gì đó như thế này (Java):

public interface A { 
    void foo(); 
} 

public interface B { 
    ... 
} 

public class BImpl implements B { 
    public B(A a) { ... } 
    ... 
} 

public class AImpl implements A { 
    private B b = new BImpl(this); 
    ... 
} 
0

Hãy suy nghĩ về thiết kế của bạn. Làm thế nào A và B có liên quan tức là nếu B là một phần của A thì thành phần là tốt. Về cơ bản, có vài cách để bạn có thể truy cập lớp khác 1. Bằng cách vượt qua tham khảo 2. Thành phần/Inheritance 3. Bạn bè lớp

1

Với bản cập nhật của bạn tôi sẽ cung cấp cho bạn một câu trả lời khác nhau.

tôi có thể nghĩ ra bốn lựa chọn

  1. Vượt qua một thể hiện của StateMachine vào mỗi State và đừng lo lắng về điều đó.Điều này kết hợp chúng lại với nhau nhưng có thể lập luận rằng chúng có liên quan chặt chẽ.

  2. Như đã được đề cập tạo giao diện chỉ chứa các phương thức trên StateMachine mà bạn muốn hiển thị với State và chuyển số này vào State. Đây là một cải tiến khi bạn giới hạn những gì State có thể làm cho lớp học StateMachine của bạn.

  3. Cũng được đề cập là việc sử dụng Observer/Observable. Ở đây, State của bạn sẽ tạo sự kiện và kích hoạt chúng cho tất cả các nhà quan sát. Trong trường hợp này, StateMachine của bạn sẽ phải quan sát tất cả các số State của bạn và phản ứng tương ứng. Điều này là hoàn toàn hợp lệ nhưng có lẽ một chút quá phức tạp, chắc chắn để bắt đầu với.

  4. Cách tiếp cận khác là sử dụng một cái gì đó như là EventBus, được tạo bởi StateMachine và được chuyển vào mỗi State. State có thể kích hoạt sự kiện trên xe buýt sự kiện. StateMachine có thể nghe sự kiện trên xe buýt sự kiện và phản ứng tương ứng. Đây là sự đơn giản hóa của mẫu Observer.

Các vấn đề liên quan