2010-01-26 35 views
17

Có sự khác biệt nào về mặt triển khai hay không như cách thiết kế bố cục có thể khác với ủy quyền. Ví dụ, mã bên dưới dường như đang thực hiện ủy quyền vì người dùng không thể truy cập đối tượng đã soạn (ví dụ "a") mà không sử dụng b. Do đó, người dùng sẽ cần phải gọi các giao diện của lớp b và sau đó "lớp b" gọi các giao diện thích hợp của "lớp a" làm cho nó ủy nhiệm. Điều này có nghĩa không ?Thành phần so với đoàn đại biểu

Class A { 
friend class B; 
private: 
A(){}; //dont want user to instantiate this class object since it wont sense without any context. Just like a room with no house. 
void PrintStructure(){}; 
}; 

Class B{ 
public: 
void PrintStructure(){a.PrintStructure();} //delegate 

private: 
A a; //composition 
}; 

Trả lời

31

Thuật ngữ "thành phần" thường được sử dụng dưới dạng mô hình đối tượng dưới dạng biểu thức của mối quan hệ "có một" và là một dạng liên kết (một kết hợp khác). Điều này thường được tương phản với "thừa kế" ("là-một" mối quan hệ). Vì vậy:

Sự khác nhau giữa bố cục và tổng hợp là gì? Thành phần ngụ ý rằng đứa trẻ không thể tồn tại mà không có bối cảnh của phụ huynh.

Ví dụ: một Ngôi nhà có một hoặc nhiều Phòng. Đó là mối quan hệ sáng tác. Xóa nhà và các phòng cũng chấm dứt tồn tại. Nhà cũng có một số người cư ngụ, là trường hợp của Người. Đó là một mối quan hệ tập hợp bởi vì những người đó tồn tại bên ngoài bối cảnh của ngôi nhà đó.

Ủy quyền không có gì khác ngoài chi tiết triển khai. Một lớp có giao diện công khai mô tả trạng thái và hành vi của nó. Cách triển khai đó không liên quan. Nó có thể ủy quyền cho các đối tượng khác hay không.

Bạn sẽ lưu ý rằng cả A và B từ ví dụ của bạn đều có cùng giao diện bên ngoài. Đó là phổ biến hơn để làm một cái gì đó như thế này:

// this represents an interface 
class A { 
public: 
    virtual void printStructure() = 0; 
} 

với các lớp bê tông:

class ConcreteA : A { 
public: 
    virtual void printStructure() { ... } 
} 

class DelegateA : A { 
public: 
    DelegateA(A& a) { this.a = a; } 
    virtual void printStructure() { a.printStructure(); } 
private: 
    A a; 
} 

Excuse My lẽ C++ lỗi cú pháp. Tôi hơi bị gỉ.

+0

Nếu thành phần ngụ ý rằng trẻ không thể tồn tại mà không có bối cảnh của phụ huynh thì người dùng có nên không bao giờ được phép tạo đối tượng của lớp được tạo không? Ví dụ: ví dụ tinh tế của tôi sẽ là lớp A {friend Class B; riêng tư: A() {}; void PrintStructure() {}; }; Lớp B {public: void PrintStructure() {a.PrintStructure();} // ủy nhiệm riêng: A a; //thành phần }; Bây giờ lớp B có lớp A. Một người dùng chỉ phải sử dụng các giao diện lớp B để thay đổi hành vi của lớp A và lớp B nên ủy nhiệm các nhiệm vụ đó cho các hàm hạng A. Thiết kế này có tốt không? –

+0

@Frank: Các lớp bạn bè là một cách để thực hiện loại mối quan hệ này. Mặc dù họ không ủng hộ tôi. Một giải pháp thanh lịch hơn là có hàm khởi tạo cho Room để yêu cầu một cá thể của House, sau đó trở thành "parent" của nó. – cletus

+0

Bạn sẽ viết mã như thế nào trong ví dụ của tôi? Hơn nữa, tôi không muốn người dùng có thể khởi tạo đối tượng A vì sẽ không có ý nghĩa khi thực hiện bất kỳ thao tác nào trên A mà không có ngữ cảnh B. –

7

Có một vài sự khác biệt tôi thấy:

  • Phái đoàn bao gồm các phương pháp tái xuất khẩu; trong mối quan hệ thành phần, các phương thức đối tượng bên trong chỉ có thể được sử dụng một cách riêng tư và không được tiếp xúc lại.
  • Thành phần thường ngụ ý một số loại ngữ nghĩa quyền sở hữu có ý nghĩa đối với vòng đời đối tượng; đối tượng cha mẹ "sở hữu" đứa trẻ và đứa trẻ không có nhiều lý do để tồn tại một mình. Phái đoàn không có ý nghĩa này.

Mã bạn hiển thị sử dụng ủy quyền và liên kết; hiệp hội có thể là thành phần, nhưng rất khó để nói mà không có bối cảnh rộng hơn hoặc nhiều thông tin hơn về các đối tượng (nó có thể khá tinh tế và chủ quan khi một liên kết trở thành một thành phần).

+0

Phương thức xuất không cần thiết để ủy quyền. Từ Wikipedia: "Trong cách sử dụng ban đầu, phái đoàn đề cập đến một đối tượng dựa vào một đối tượng khác để cung cấp một tập hợp các chức năng được chỉ định". – danben

4

Thành phần là về mối quan hệ giữa các đối tượng.

Ủy quyền sắp chuyển công việc từ một đối tượng này sang đối tượng khác.

Đây thực sự là những mối quan tâm khác nhau (nhưng đôi khi có liên quan).

Những gì bạn có là B bao gồm A (B đề cập đến A). B cũng giao cho một phương pháp của nó để A.

Nhưng vì việc B sử dụng A là riêng tư (được đóng gói hoàn toàn trong hộp đen của B) nên tôi sẽ không gọi B là "thành phần" của B. Tôi sẽ sử dụng "thành phần" chỉ khi lớp A có thể được truy cập từ B. Điều quan trọng ở đây là nếu mô hình logic của B "có-a" A.

Trong trường hợp của bạn, B được thực hiện theo A. Vì đây là một mối quan tâm thực hiện nó có thể được coi là không phải là một phần của mô hình logic của B. Tức là, bạn có thể nói chuyện thông minh về B mà không cần nói hoặc quan tâm về A.

Điều đó tất cả đã nói, công cụ này thực sự chỉ quan trọng đối với các công cụ tạo mô hình của PHB và UML. Hoặc có lẽ nếu bạn đang nghiên cứu các mẫu thiết kế. Tôi sẽ không quá hung hăng với nó.

[PHB => Boss tóc nhọn]

+0

Điều đó có nghĩa là trong bố cục đối tượng sáng tác (trong trường hợp này "a") phải được công khai? Bằng cách này, người dùng sẽ truy cập bằng cách sử dụng b ví dụ B b; b.a.PrintStructure(); // giả sử hàm thành viên là công khai. –

+0

Không có quyền hoặc sai tuyệt đối ở đây. Điều quan trọng là mục đích của các lớp học. Bạn không nên làm cho thành viên "a" của lớp B công khai chỉ vì một số khái niệm "thành phần". Thay vì xem xét nếu "a" là quan trọng đối với các mã bằng cách sử dụng một thể hiện của lớp B. Nếu mã bằng cách sử dụng B cần để có được "a", sau đó phải có một cách (phương pháp) trên B để truy cập nó. Trong ví dụ của bạn, "a" là riêng tư, vì vậy sự tồn tại và sử dụng của nó trong B hoàn toàn bị ẩn khỏi mã sử dụng lớp B. Đây thường là một điều tốt. Thêm: http://en.wikipedia.org/wiki/Information_hiding http://en.wikipedia.org/wiki/Object_composition – rickmode

+0

Cảm ơn, tôi đã bắt đầu một chuỗi khác nếu trả về tham chiếu đến thành viên riêng trong phần tóm tắt thành phần OOP . Trong trường hợp của tôi B phải có A và người dùng cần phải thiết lập một số thích hợp của A mà sẽ yêu cầu anh ta/cô ấy một số cách để có được A. Tôi không muốn sử dụng đoàn hoặc là sẽ yêu cầu tôi để lộ phương pháp trong B cho mọi phương pháp trong A. –

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