2010-05-25 18 views
5

Tôi có một số mã mà trông giống như:Tôi làm cách nào để sửa sự ghen tị của tính năng trong trường hợp này?

class Parent { 
private Intermediate intermediateContainer; 
public Intermediate getIntermediate(); 
} 

class Intermediate { 
private Child child; 
public Child getChild() {...} 
public void intermediateOp(); 
} 

class Child { 
public void something(); 
public void somethingElse(); 
} 

class Client { 
private Parent parent; 

public void something() { 
    parent.getIntermediate().getChild().something(); 
} 

public void somethingElse() { 
    parent.getIntermediate().getChild().somethingElse(); 
} 

public void intermediate() { 
    parent.getIntermediate().intermediateOp(); 
} 
} 

Tôi hiểu đó là một ví dụ về "tính năng ghen tị" mã mùi. Câu hỏi là, cách tốt nhất để sửa chữa nó là gì? Bản năng đầu tiên của tôi là đặt ba phương thức này vào cha mẹ:

parent.something(); 
parent.somethingElse(); 
parent.intermediateOp(); 

... nhưng tôi cảm thấy như mã trùng lặp này và cắt API của lớp cha mẹ (đã khá bận).

Tôi có muốn lưu trữ kết quả getIntermediate() và/hoặc getChild() và giữ tham chiếu của riêng tôi cho các đối tượng này không?

+0

Cảm ơn bạn! Tất cả những câu trả lời này đều hữu ích, vì vậy tôi upvoted chúng – RMorrisey

Trả lời

5

Theo kinh nghiệm của tôi, hãy làm những gì bạn đề nghị (làm cho tất cả các phương pháp chỉ gọi là "cấp độ tiếp theo") sẽ giúp chiếu sáng những thay đổi đối với API của bạn mà bạn nên thực hiện. Vì vậy, có, thực hiện những thay đổi đó mặc dù nó làm lộn xộn API của bạn và bạn có thể khám phá cách thích hợp để giải quyết các vấn đề.

"Thực tế" là một thứ gì đó có Khách hàng khi cần có (hoặc muốn có) thứ gì đó khác. Điều này ngụ ý rằng một trong hai chức năng của thứ khác đó ở sai chỗ hoặc điều yêu cầu chức năng đó ở sai chỗ. Thật không may, thật khó để đưa ra các ví dụ cụ thể mà không có mã toàn diện hơn.

Khi bạn cuối cùng nhận ra "vấn đề" là gì, tuy nhiên, các giải pháp có thể không dễ thực hiện. Đó là một bummer, nhưng giữ cho cuộc chiến tốt và refactor đối với giải pháp đó anyway!

+1

Tôi nhận ra rằng trong trường hợp của tôi, Child (nguồn dữ liệu cho thành phần giao diện người dùng của tôi) không phải được sở hữu hoặc quản lý bởi thành phần cha của anh ta, và anh ta chỉ thuộc về cha mẹ khi Tôi bắt đầu sử dụng anh ta trong Client (một thành phần UI khác làm việc song song). Tôi kéo công trình của Child lên một tầng lớp cao hơn sở hữu cả Parent và Client, và chuyển nó thành cả hai. – RMorrisey

10

Đây không phải là chính xác Tính năng ghen tị, nhưng nhiều vấn đề về ghép nối giữa các lớp này và vi phạm Luật Demeter nhất định http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/general-formulation.html. Suy nghĩ đầu tiên của bạn về việc có các phương thức trực tiếp trên cha mẹ là một điều tốt. Khách hàng không cần phải gọi qua ngăn xếp như vậy.

Nếu bạn lo lắng về việc cha mẹ quá bận rộn, có thể bạn có quá nhiều chức năng trong đó và nó phải được chia thành một số lớp nhỏ hơn. Các lớp học nên được đơn độc.

3

Ai đang truy cập Client? Bạn có cần giữ riêng tư số parent của mình hay bạn nên để lộ mã đó để mã gọi có thể điều hướng đến nơi các tính năng cần thiết?

Nếu bạn lo lắng về việc phơi bày hoàn toàn parent, một tùy chọn khác là trích xuất giao diện từ Parent và hiển thị giao diện đó từ Client.

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