Việc sử dụng Hiệp hội, Tập hợp và Thành phần là gì?


20

Tôi đã trải qua rất nhiều lý thuyết về đóng gói và ba kỹ thuật thực hiện nó, đó là Hiệp hội, Tập hợp và Thành phần.

Những gì tôi tìm thấy là :

Đóng gói

Đóng gói là kỹ thuật làm cho các trường trong một lớp riêng tư và cung cấp quyền truy cập vào các trường thông qua các phương thức công khai. Nếu một trường được khai báo là riêng tư, nó không thể được truy cập bởi bất kỳ ai bên ngoài lớp, do đó ẩn các trường trong lớp. Vì lý do này, đóng gói cũng được gọi là ẩn dữ liệu.

Đóng gói có thể được mô tả như một hàng rào bảo vệ ngăn chặn mã và dữ liệu được truy cập ngẫu nhiên bởi mã khác được xác định bên ngoài lớp. Truy cập vào dữ liệu và mã được kiểm soát chặt chẽ bởi một giao diện.

Lợi ích chính của việc đóng gói là khả năng sửa đổi mã được triển khai của chúng tôi mà không vi phạm mã của những người khác sử dụng mã của chúng tôi. Với tính năng này, Encapsulation mang lại khả năng bảo trì, tính linh hoạt và khả năng mở rộng cho mã của chúng tôi.

Hội

Hiệp hội là một mối quan hệ trong đó tất cả các đối tượng có vòng đời riêng và không có chủ sở hữu. Hãy lấy một ví dụ về Giáo viên và Học sinh. Nhiều học sinh có thể liên kết với một giáo viên và một học sinh có thể liên kết với nhiều giáo viên, nhưng không có quyền sở hữu giữa các đối tượng và cả hai đều có vòng đời riêng. Cả hai có thể tạo và xóa độc lập.

Tập hợp

Tập hợp là một hình thức chuyên môn của Hiệp hội nơi tất cả các đối tượng có vòng đời riêng, nhưng có quyền sở hữu và một đối tượng con không thể thuộc về đối tượng cha mẹ khác. Hãy lấy một ví dụ về Bộ và giáo viên. Một giáo viên không thể thuộc nhiều bộ phận, nhưng nếu chúng tôi xóa bộ phận đó, đối tượng giáo viên sẽ không bị phá hủy. Chúng ta có thể nghĩ về nó như là một mối quan hệ của người Viking.

Thành phần

Thành phần lại là một hình thức tổng hợp chuyên biệt và chúng ta có thể gọi đây là một mối quan hệ chết chóc. Nó là một loại tập hợp mạnh mẽ. Đối tượng con không có vòng đời của chúng và nếu đối tượng cha mẹ xóa tất cả đối tượng con cũng sẽ bị xóa. Hãy lấy lại một ví dụ về mối quan hệ giữa Nhà và phòng. Nhà có thể chứa nhiều phòng nhưng không có cuộc sống độc lập của một phòng và bất kỳ phòng nào cũng không thể thuộc về hai ngôi nhà khác nhau. Nếu chúng tôi xóa nhà, căn phòng sẽ tự động bị xóa.

Câu hỏi là:

Bây giờ tất cả là những ví dụ thực tế. Tôi đang tìm kiếm một số mô tả về cách sử dụng các kỹ thuật này trong mã lớp thực tế. Ý tôi là điểm nào để sử dụng ba kỹ thuật khác nhau để đóng gói , Làm thế nào những kỹ thuật này có thể được thực hiệnCách chọn kỹ thuật nào được áp dụng tại thời điểm đó.


1
Xin lưu ý rằng Tập hợp, Thành phần và Hiệp hội không phải là kỹ thuật để thực hiện đóng gói. Một đóng gói cũng có thể tồn tại ngay cả khi chỉ có một lớp / đối tượng. Đóng gói chỉ là một tính năng thiết yếu trong Định hướng đối tượng để ẩn dữ liệu của đối tượng của bạn.
Maxood

1
"Một giáo viên duy nhất KHÔNG thể thuộc về nhiều bộ phận" thực sự? Bạn không nhận thấy tài nguyên của bạn đã sửa đổi nội dung?
KNU

Tôi đã quản lý để sử dụng Thành phần để xác định Rễ tổng hợp DDD và các thực thể của chúng khi thực hiện Thiết kế hướng tên miền. Một cách sử dụng mới cho một quy ước cũ.
Jonn

Câu trả lời:


12

Sự khác biệt giữa liên kết, tổng hợp và thành phần như bạn mô tả nó là một di sản quay trở lại thời kỳ cũ của quản lý bộ nhớ thủ công. Ví dụ, trong C ++, bộ nhớ được sử dụng bởi các đối tượng phải được giải phóng bằng tay và do đó, điều tối quan trọng là phải thiết kế cẩn thận vòng đời của các đối tượng cấu thành. Mặc dù sự khác biệt giữa tổng hợp và sáng tác vẫn đang được dạy bởi nhiều sách giáo khoa, nhưng về cơ bản nó không liên quan khi lập trình trong môi trường với quản lý bộ nhớ tự động. Nếu bạn có bộ sưu tập rác, tất cả chúng chỉ là thành phần, thời gian.

Mặt khác, đóng gói là một nguyên tắc chung hơn nhiều so với những gì bạn mô tả. Đây là ý tưởng đầu tiên của việc đóng gói dữ liệu và các chức năng hoạt động trên dữ liệu này trong một mô-đun. Một cách để thực hiện điều này là bằng cách giữ trạng thái của mô-đun riêng tư và phơi bày các thay đổi đối với trạng thái đó thông qua các dịch vụ công cộng. Vì vậy, khách hàng không thể tự mình truy cập trạng thái mà phải nói với mô-đun ý định của họ bằng cách gửi tin nhắn. Vì vậy, đóng gói không chỉ giới hạn cho các đối tượng mà còn áp dụng cho các dịch vụ. Trên thực tế, một cách nhìn vào các đối tượng là xem chúng như các dịch vụ.

Đây là một ví dụ về đóng gói

public class Counter {
    private int n = 0;
    public int inc() { return n++; }
}

hoặc tương tự bằng cách sử dụng các hàm lambda

var counter = (function() {
    var n = 0;
    var inc = function() { return n++; }
    return inc;
})();

Trong cả hai trường hợp, dữ liệu, đó là biến n, được gói cùng với hàm inchoạt động trên nó. Và không có cách nào mà bất kỳ chức năng nào khác có thể truy cập n, do đó chúng tôi có một mô-đun đóng gói cung cấp tính như một dịch vụ.

NB: phơi bày tất cả trạng thái bên trong của đối tượng thông qua các bộ truy cập thực sự là vi phạm đóng gói. Than ôi, đó là một vi phạm phổ biến đến mức nhiều người sẽ nhầm lẫn nó với thiết kế hướng đối tượng tốt.


2
Quản lý bộ nhớ tự động không có gì để làm với các mối quan hệ đối tượng. Một sơ đồ đối tượng tự nó cho người lập trình biết cách mã hóa các lớp, giao diện và phương thức của chúng theo các yêu cầu của hệ thống đang được xem xét.
Maxood

2
Ngoài ra còn có một sự cân nhắc bên ngoài bộ nhớ. Trong thiết kế dữ liệu hoặc có lẽ tuần tự hóa. Trong thành phần, bạn có thể cần có các ràng buộc khóa ngoại khác nhau trong RDBMS hoặc có thể thay đổi cách bạn xử lý tuần tự hóa một đối tượng nếu nó có con hỗn hợp so với con tổng hợp hoặc các đối tượng liên quan.
Chris

8

Đóng gói là kỹ thuật làm cho các trường trong một lớp riêng tư và cung cấp quyền truy cập vào các trường thông qua các phương thức công khai. Nếu một trường được khai báo là riêng tư, nó không thể được truy cập bởi bất kỳ ai bên ngoài lớp, do đó ẩn các trường trong lớp. Vì lý do này, đóng gói cũng được gọi là ẩn dữ liệu.

    public class Test{

    private String name;

       private int age;

       public int getAge(){
          return age;
       }

       public String getName(){
          return name;
       }
    }

Tham khảo câu hỏi này cũng .

Hiệp hội chỉ ra mối quan hệ giữa các đối tượng. ví dụ: Máy tính sử dụng bàn phím làm thiết bị đầu vào.

Một liên kết được sử dụng khi một đối tượng muốn một đối tượng khác thực hiện một dịch vụ cho nó.

Tập hợp là một trường hợp đặc biệt của hiệp hội. Một liên kết định hướng giữa các đối tượng. Khi một đối tượng 'có-một' một đối tượng khác, thì bạn đã có một tập hợp giữa chúng.

ví dụ: Phòng có một cái bàn, nhưng cái bàn có thể tồn tại mà không có phòng.

    class Room {

      private Table table;

      void setTable(Table table) {
        this.table = table;
      }

    }

Thành phần là một trường hợp đặc biệt của tập hợp. Thành phần là hạn chế hơn. Khi có một thành phần giữa hai đối tượng, đối tượng sáng tác không thể tồn tại mà không có đối tượng khác. Hạn chế này không có trong tập hợp. ví dụ: các phòng trong một ngôi nhà, không thể tồn tại sau vòng đời của ngôi nhà.

    class House {

      private  Room room;

      House(Room roomSpecs) {
        room = new Room(roomSpecs);
      }

    }

Thành phần là một kỹ thuật thiết kế để thực hiện mối quan hệ có-có trong các lớp, theo Kế thừa hoặc đối tượng Thành phần để sử dụng lại mã.

Một trong những cách thực hành tốt nhất trong lập trình Java là sử dụng thành phần trên kế thừa


Làm thế nào để trả lời câu hỏi này?
gnat

1

Sử dụng các kỹ thuật đó thường dẫn đến các thực tiễn thiết kế như RẮN hoặc các mẫu thiết kế khác nhau .

Quan điểm của việc sử dụng các mẫu, thực tiễn và như vậy là để mô tả một giải pháp cho một vấn đề cụ thể cũng có thể duy trì và mở rộng. Bạn chỉ cần có đủ kinh nghiệm để biết nơi sử dụng mô hình hoặc kỹ thuật nào.


1

Tôi thẳng thắn cảm thấy rằng những khái niệm này được dạy ở học thuật có tầm quan trọng của chúng trong bối cảnh định hướng đối tượng và thiết kế lớp học. Những khái niệm này hỗ trợ chúng ta rất nhiều khi mô hình hóa một hệ thống từ đầu. Hiệp hội, Tập hợp và Thành phần chỉ thuộc về sơ đồ lớp của UML và hoàn toàn độc lập với các ràng buộc công nghệ như các vấn đề về bộ nhớ.

Hơn nữa, bạn cũng phải xem xét các mục tiêu kinh doanh hoặc cấp độ cao hơn của hệ thống mà bạn đang lập mô hình. Chúng tôi có các đối tượng như Nhà và Phòng trong hệ thống của chúng tôi đang được xem xét, nhưng không thể liên quan chặt chẽ (thông qua thành phần). Ví dụ, nếu tôi đang mô hình hóa một hệ thống bất động sản thì tôi có thể phải biết phòng nào thuộc về ngôi nhà nào. Nhưng hãy để tôi mô hình hóa một hệ thống khảo sát hoặc điều tra dân số nơi tôi muốn biết có bao nhiêu người đang sống trong mỗi phòng của một ngôi nhà trong một khu vực nhất định, sau đó tôi không cần phải liên kết một căn phòng với một ngôi nhà thông qua bố cục.

Một ví dụ khác có thể là của một vườn cây và một số loại trái cây. Hãy nói rằng tôi chỉ có thể xem xét một vườn cây khi tôi có cây táo được trồng bên trong nó. Điểm mấu chốt là các yêu cầu của hệ thống tổng thể có vấn đề rất nhiều.

Đóng gói là một trong những trụ cột của Thiết kế hướng đối tượng. Bạn cần bó dữ liệu của bạn và các thao tác bạn sẽ thực hiện trên dữ liệu của mình. ngoài ra, bạn phải ẩn các thuộc tính nhất định của đối tượng của mình khỏi thế giới bên ngoài để cho phép đối tượng đó tồn tại ở trạng thái hợp lệ. Khi 2 đối tượng tương tác, chúng phải tương tác với nhau thông qua một giao diện. Và đó là những gì đóng gói đảm bảo khi chúng tôi thiết kế hệ thống OO của mình.

Đây là cách các khái niệm này được áp dụng cho mã:

HIỆP HỘI: Hiệp hội chỉ ra mối quan hệ giữa các đối tượng. Nó cho phép lập trình viên biết những phương thức nào để viết trong các lớp của họ để làm cho chúng tương tác với nhau. Bạn có thể tìm thấy một số ví dụ về mã và sơ đồ lớp để hiểu liên kết. Trong ví dụ của bạn về Dạy và Học sinh, có một mối quan hệ của việc dạydạy bởi . Vì vậy, bạn sẽ chỉ cần viết một tập hợp các phương thức (giao diện được gọi là kỹ thuật) thông qua đó bạn có thể biết học sinh nào có giáo viên nào và giáo viên nào có học sinh gì. Hiệp hội cũng cho phép người điều hành hệ thống hỗ trợ người thiết kế cơ sở dữ liệu về các thuộc tính và trường cần được giữ trong cơ sở dữ liệu.

THÀNH PHẦN: Nếu một đối tượng là một phần không thể thiếu của một đối tượng khác, thì tôi có thể phải chỉ ra mối quan hệ này trong hàm tạo của đối tượng kia. Ví dụ: trong kịch bản Nhà và Phòng của bạn, chúng tôi có thể viết mã sau đây trong trường hợp chúng tôi muốn biết phòng nào thuộc loại nhà nào.

class House{
          string _HouseType;   
     public:    
    void setHouseType(string house_type)
     {
        this. _HouseType = house_type;
     } 

     string getHouseType()
    {
       return _HouseType;
    }
};



 House HouseObject = new House();


class Room{

 public: 
 Room(string HouseType) {
       this._HouseType = HouseObject.getHouseType();  //as in my system a room cannot exist without a house

 } 

};

Lập trình viên cũng sẽ đảm bảo trong khi gọi các hàm hủy của đối tượng, rằng kẻ hủy diệt của đối tượng khác cũng được gọi. Điều này là rất quan trọng.

AGGREGATION: Hãy nói rằng nếu mối quan hệ giữa các đối tượng yếu thì chúng ta đối với lập trình viên, điều đó có nghĩa là sử dụng một biến thể hiện thay thế để chỉ ra mối quan hệ. Và sau đó viết một bộ biến đổi functon (setter) để cung cấp giá trị cho đối tượng đó từ một đối tượng khác.

class Department{

 string dept_name;

public:
   void setDeptName(string name)
   {
        this.dept_name=name;
   }

   string getDeptName()
   {
        return dept_name; 
   }

};



 Department DepartmentObject = new Department();

class Teacher{

 string dept_name;

public:

  setDeptName(string name)
  {
     this.dept_name = DepartmentObject.getDeptName();  //You only need to invoje this method when needed (aggregation)
  }
}

};

1

OK, hãy ánh xạ điều này đến một số thuộc tính cốt lõi thay vì các khái niệm trừu tượng chỉ có ý nghĩa một khi bạn hiểu ý nghĩa của chúng. Giống như một số người bình luận tôi không đồng ý với câu trả lời được chấp nhận, tôi nói đây là những khái niệm độc lập với quản lý bộ nhớ.

Đóng gói

Bạn muốn che giấu sự phức tạp khỏi máy khách, chỉ xuất bản những thứ quan trọng theo quan điểm của khách hàng, giúp mọi thứ dễ dàng hơn cho khách hàng. Là một phần thưởng, bạn có được sự chắc chắn rằng không có gì có thể gây rối với mã được đóng gói. Miễn là bạn tôn trọng giao diện và chức năng, bạn có thể làm lại mọi thứ và yên tâm rằng bạn sẽ không phá vỡ bất cứ điều gì. Sự phụ thuộc chỉ trên giao diện được công bố.

Đóng gói là một trong những trụ cột chính của định hướng đối tượng. Nó không phải là một mô hình, nó là một nguyên tắc và nó có thể áp dụng cho logic và dữ liệu giống nhau. Nó chỉ là một lợi ích cơ bản của việc sử dụng các lớp ở nơi đầu tiên, không phải là thứ bạn sẽ thấy được nêu rõ trong sơ đồ hoặc tài liệu thiết kế.

Hội

Đây là một khái niệm rất lỏng lẻo, về cơ bản chỉ mô tả một sự phụ thuộc giữa các đối tượng. Một đối tượng biết về sự tồn tại của một đối tượng khác và có thể sử dụng chức năng của nó tại một số điểm. Trong một sơ đồ, hiệp hội sẽ cảnh báo bạn rằng có một sự phụ thuộc và việc thay đổi một đối tượng có thể tác động đến đối tượng khác. Nó không phải là một kỹ thuật để áp dụng khi bạn có một số vấn đề cần giải quyết, nó giống như một thực tế của cuộc sống mà bạn nên biết khi nó ở đó. Đó là một mối quan hệ. Giống như một hóa đơn có một tài sản Đơn đặt hàng. Cả Order và Invoice đều có vòng đời riêng. Một là về hàng hóa và thứ hai là về thanh toán, về cơ bản làm cho chúng độc lập nhưng điều quan trọng là phải biết hàng hóa nào đang được thanh toán.

Ngăn chặn

Tôi đang thêm điều này bởi vì nó thuộc về bộ và sẽ làm cho tổng hợp có ý nghĩa hơn. Tôi không nghe thấy thuật ngữ được sử dụng trong bối cảnh SE nhiều nữa nhưng tôi nghĩ nó vẫn hữu ích. Ngăn chặn ngụ ý đóng gói nhưng nghiêm ngặt về các thể hiện đối tượng riêng tư đối với lớp chứa. Chức năng của các đối tượng chứa được tiếp xúc có chọn lọc thông qua các giao diện công cộng. Lớp chứa điều khiển vòng đời của các đối tượng được điều khiển. Bạn sử dụng điều này khi bạn cần một số tính năng của một lớp hiện có để làm cho lớp chứa có chức năng. Đây có thể là một trình phân tích cú pháp XML và ứng dụng khách của lớp chứa có thể không bao giờ nhìn thấy hoặc biết bất cứ điều gì liên quan đến XML. Như một phép ẩn dụ, hãy nghĩ về đối tượng chứa đựng như một nhân viên văn phòng hỗ trợ. Khách hàng không bao giờ gặp những người này nhưng họ cần thiết để cung cấp dịch vụ.

Tập hợp

Điều này rất giống với việc ngăn chặn ngoại trừ kiểm soát vòng đời và khả năng hiển thị của các đối tượng tổng hợp. Các đối tượng tổng hợp đã có sẵn trong một bối cảnh khác và được quản lý bởi một thực thể khác. Bộ tổng hợp chỉ đơn thuần là cung cấp một mặt tiền, một cổng thông tin cho các đối tượng tổng hợp. Khi máy khách gửi địa chỉ tổng hợp, nó sẽ nhận được giao diện của chính đối tượng tổng hợp, chứ không phải là một trình bao bọc xung quanh nó. Điểm của tổng hợp là cung cấp một nhóm hợp lý của sự vật. Hãy nghĩ về một điểm truy cập đến các dịch vụ hoặc một số đối tượng trình bao bọc khác.

Thành phần

Dường như với tôi đây là thuật ngữ hiện đại hơn để ngăn chặn, có thể bởi vì nó được đặt trong một cuốn sách nổi tiếng có nguồn gốc tương đối gần đây. Trong trường hợp ngăn chặn tập trung vào các khía cạnh kỹ thuật của các mối quan hệ đối tượng, thành phần thường được sử dụng trong bối cảnh của các quyết định thiết kế, cụ thể hơn là một sự thay thế linh hoạt hơn cho kế thừa.

Nó không nói nhiều về bản chất của các mối quan hệ đối tượng hoặc quyền sở hữu, nó chỉ cho thấy chức năng được thực hiện bằng cách kết hợp chức năng của các lớp hiện có. Do đó, tôi cho rằng nó không thuộc về loạt bài này vì nó không nói gì về các khía cạnh kỹ thuật của việc triển khai nơi những người khác làm.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.