2010-10-12 25 views
5

Tôi gặp sự cố trong một lớp của tôi sử dụng mẫu trang trí.Cách xử lý tham chiếu 'này' trong kiểu trang trí

Sự cố phát sinh khi đối tượng bên trong sử dụng tham chiếu "này" trong các cuộc gọi đến các đối tượng khác. Điều này làm cho tất cả các cuộc gọi từ đối tượng nhận được tham chiếu "này" được thực hiện trực tiếp đến đối tượng bên trong, mà không đi qua bên ngoài đầu tiên.

Cách thông thường để giải quyết vấn đề này là gì?

Cảm ơn.

+2

Có một số cách để diễn giải những gì bạn đã mô tả trong phân cấp lớp. _djechelon_ cung cấp một câu trả lời cho một giải thích câu hỏi của bạn ... Tôi có một giải thích trong tâm trí để bạn có thể muốn cung cấp cho chúng tôi với một số đoạn mã. – Isaac

Trả lời

2

Đối tượng có giá trị tiềm ẩn: danh tính của chúng (có thể được kiểm tra bằng cách áp dụng ==). Khi bạn quấn chúng, bạn có thể ẩn danh tính đó một cách hiệu quả (tệ hơn, bạn cũng phơi bày một bản sắc có khả năng gây hiểu lầm, danh tính của trình bao bọc). Vì vậy, một cách tiếp cận rõ ràng là bù đắp cho điều này bằng cách phơi bày danh tính của đối tượng thông qua một cách khác - một cách rõ ràng. Ví dụ. bạn có thể giới thiệu một phương thức Object getIdentity(), trả về một đối tượng thực sự đại diện cho danh tính dự định và cho phép áp dụng == cho nó.

Nhược điểm lớn nhất là bạn vẫn cho phép == trên chính trang trí, ví dụ: một mối nguy hiểm rằng:

  • là đủ tự nhiên để bị lừa vào nó (identity == decorator thay vì identity == decorator.getIdentity())
  • âm thầm làm điều sai (so sánh với một ngoại lệ thời gian chạy - may mắn gỡ lỗi tốt mà)

Vấn đề sẽ không tồn tại nếu, ví dụ, các đối tượng có một phương pháp như:

protected Object getIdentity() { 
    return this; 
} 

Trên đó == nhà điều hành wo uld được xác định, do đó, một wrapper cũng có thể quấn danh tính của đối tượng được bao bọc, thay vì thay thế nó bằng chính nó.

+0

Tôi nghĩ rằng đây là cách tôi sẽ đi. Thêm một setIdentity và getIdentity vào giao diện cơ sở của tôi sẽ làm cho nó có thể có được chức năng mong muốn của tôi. – monoceres

1

Nói chung, bạn không thể. Trừ khi bạn phân lớp lớp trang trí của mình, lớp học bên trong của bạn sẽ miễn phí để gọi bất kỳ phương thức nào sử dụng chính nó làm thông số và không có cách nào để thay đổi nó.

Khi sử dụng mẫu trang trí, lớp trang trí phụ trách việc chuyển số tham chiếu này (tham chiếu trang trí) đến các phương pháp khác. Theo quan điểm của tôi, người trang trí là thứ tương tự nhất với một proxy: đối tượng được trang trí bên trong hoàn toàn được bao bọc trong các trang trí của nó và không thể truy cập trực tiếp. Vì vậy, bạn phải tìm cho mình một cách để không cho phép đối tượng được trang trí của bạn truy cập trực tiếp vào các đối tượng khác và có thể vượt qua this tham chiếu

1

Nội dung bạn mô tả là sự pha trộn giữa mẫu trang trí và mẫu. Mẫu trang trí cho phép bạn thêm hành vi động vào một đối tượng (thông qua việc sử dụng cơ chế giống như proxy). Mẫu khuôn mẫu phá vỡ một thuật toán thành nhiều phương thức để bạn có thể thay đổi hành vi của đối tượng bằng cách thay thế các phương thức thông qua phân lớp, hoặc trong trường hợp của bạn, trình trang trí.

Bởi vì trang trí là một loại proxy, chúng giữ một tham chiếu đến đối tượng đích (hoặc trang trí khác bọc n-lớp sâu xung quanh đối tượng mục tiêu). Nhưng mục tiêu thường không theo dõi các trang trí của nó hoặc đưa ra bất kỳ giả thiết nào liên quan đến trang trí.Vì vậy, mỗi khi hành vi của đối tượng mục tiêu bị thay đổi bằng cách thêm hoặc loại bỏ trang trí ngoài cùng, thiết kế của bạn sẽ cần cập nhật đối tượng đích với tham chiếu đến trang trí ngoài cùng hoặc đối tượng đích sẽ cần truy vấn đối tượng khác ngoài cùng trang trí tham khảo.

Nếu đối tượng đích có thể truy vấn tham chiếu đến ngăn xếp đối tượng được trang trí từ bất kỳ đối tượng nào chịu trách nhiệm giữ nó (cái gì đó phải), thì có thể bạn đã ổn. Nếu không, đối tượng mục tiêu có thể cần phải dùng đến một đại biểu hoặc người hòa giải.

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