definition: also called a synthetic pattern, or a partial-whole pattern, is mainly used to describe the relationship between a part and the whole, the definition, the grouping of objects into a tree structure to represent the hierarchical structure of "partial-whole", which makes the user consistent in the use of individual objects and composite objects.
Class Diagram:
Role Description:
Componnent Abstract Widget Role: Defines common methods and properties that participate in a grouped object, and you can define some default behavior or properties.
Leaf widget: A leaf object that has no other branches under it, that is, the smallest unit of traversal.
Composite Branch member: A branch object that acts as a tree-shaped structure combining branch nodes and leaf nodes.
Instance:
I heard that your company recently launched a new E-book reading application, the market reaction is very good, the application of the book Mall, users can choose to buy their favorite books. Your company also attaches great importance to this project, increased the input, decided to add some additional function to this application.
Well, you know you're not going to get away with this, and it didn't take long for your leader to find you. He tells you that the current application counts the volume and volume of each book, but now you want to add the ability to count the amount of browsing and sales and the total volume and volume of all books, and hopefully you can do it.
The work of the leadership arrangement of course is to evade, you can only bite the bullet, but fortunately this function does not look very complicated.
You like to read novels, then start with the statistical function of the novel. First, through the Get_all_novels method can obtain all the novel names, and then the novel name into the Get_browse_count method can get the volume of the book, the novel into the Get_sale_count method can get the book sales. You currently have only a few known APIs to use, so start doing it!
def get_novels_browse_count
browse_count = 0
all_novels = get_all_novels ()
All_novels.each do |novel|
Browse_count + = Get_browse_count (novel) End
Browse_count end
def get_novels_sale_count
Sale_ Count = 0
all_novels = get_all_novels ()
All_novels.each do |novel|
Sale_count + = Get_browse_count (novel) End
Sale_count End
Soon you will write down the above two methods, both by acquiring all the novel names and then calculating the volume and volume of each novel, and then adding the total to the results.
The statistics of the novel are complete, and then you start to do the statistical functions of computer books, the code looks like this:
def get_computer_books_browse_count
browse_count = 0
all_computer_books = get_all_computer_books ()
All_ Computer_books.each do |computer_book|
Browse_count + = Get_browse_count (computer_book) End
Browse_count end
def Get_computer_books_sale_ Count
sale_count = 0
all_computer_books = get_all_computer_books ()
All_computer_books.each do | computer_book|
Sale_count + = Get_browse_count (computer_book) End
Sale_count End
In addition to using the Get_all_computer_books method to get all the computer titles, the other code basics are the same as in the novel statistics.
Now you have completed the statistical functions of the two categories of books, there are medical, natural, historical, legal, political, philosophical, tourism, food and so on and so on books. You suddenly realize the seriousness of some problems, the amount of work is not much, but then write down, your method will explode, so many ways to look at it, not to mention how to use.
At this time you had to ask your leader for help, and he explained your confusion. See your leader thinking for a moment, and then confidently tell you that using combination mode can not only easily eliminate your confusion, but also the ability to complete the function excellently.
He immediately showed you the code operation, first defines a statistics class, which has two methods:
Class Statistics
def get_browse_count
raise "You should override this method in subclass."
End
def get_sale_count
raise "Your should override this method in subclass."
End End
Both methods simply throw an exception because the two methods need to be overridden in the subclass.
Then define a Novelstatistics class for statistical fiction books, inherit the statistics class that you just defined, and rewrite the two methods in statistics:
Class Novelstatistics < Statistics
def get_browse_count
browse_count = 0
all_novels = get_all_novels ()
All_novels.each do |novel|
Browse_count + = Get_browse_count (novel) End
Browse_count end
def get_sale_count
Sale_ Count = 0
all_novels = get_all_novels ()
All_novels.each do |novel|
Sale_count + = Get_browse_count (novel) End
Sale_count end
In these two methods, the reading volume and sales volume of novel books are counted separately. In the same way, your leader defines a Computerbookstatistics class for counting the amount of browsing and sales of computer-like books:
Class Computerbookstatistics < Statistics
def get_browse_count
browse_count = 0
all_computer_books = Get_all_computer_books ()
All_computer_books.each do |computer_book|
Browse_count + = Get_browse_count (computer_book) End
Browse_count end
def get_sale_count
Sale _count = 0
all_computer_books = get_all_computer_books ()
All_computer_books.each do |computer_book|
Sale_count + = Get_browse_count (computer_book) End
Sale_count end
In this way, the specific statistical implementation of the various classes, there will not be the way you just that method explosion. But it's not really starting to use the combo model yet, and the show is still behind you, "leader boasted."
Then define a Medicalbookstatistics class inheritance statistics, which is used to count the volume and volume of medical books, as shown in the following code:
Class Medicalbookstatistics < Statistics
def get_browse_count
browse_count = 0
all_medical_books = get_ All_medical_books ()
All_medical_books.each do |medical_book|
Browse_count + = Get_browse_count (medical_book) End
Browse_count end
def get_sale_count
Sale_ Count = 0
all_medical_books = get_all_medical_books ()
All_medical_books.each do |medical_book|
Sale_count + = Get_browse_count (medical_book) End
Sale_count end
Do not know you found no, computer books and medical books are actually science and technology books, they can be grouped together. This time your leader defines a Technicalstatistics class for statistics on the combination of science and technology:
Class Technicalstatistics < Statistics
def initialize
@statistics = []
@statistics << Computerbookstatistics.new
@statistics << medicalbookstatistics.new
end
def get_browse_count
browse_count = 0
@statistics. Each do |s|
Browse_count + + S.get_browse_count end
Browse_count end
def get_sale_count
sale_count = 0
@statistics. Each do |s|
Sale_count + + S.get_sale_count end
sale_count end
As you can see, because this class is a combination class, there are a lot of differences from the previous classes. First Technicalstatistics has a constructor that adds computer books and medical books as subcategories to the statistics array in the constructor, and then to the Get_browse_count and Get_sale_ The Count method iterates through all the subcategories, calculates their respective browsing volume and sales volume, and then adds the total return.
The expansion of the combination mode is very good, there are no various rules and regulations, how to combine the combination, such as all the books are grouped by various categories, your leader immediately show you the statistics of all the browsing volume and sales.
Define a Allstatistics class to inherit statistics, as shown in the following code:
Class Allstatistics < Statistics
def initialize
@statistics = []
@statistics << Novelstatistics.new
@statistics << technicalstatistics.new
end
def get_browse_count
Browse_ Count = 0
@statistics. Each do |s|
Browse_count + + S.get_browse_count end
Browse_count end
def get_sale_count
sale_count = 0
@statistics. Each do |s|
Sale_count + + S.get_sale_count end
sale_count end
In Allstatistics's constructor, you add novel books and science and technology books as subcategories to the statistics array, and you are only writing these few categories right now. The same method is then used to Get_browse_count and Get_sale_count methods to count the volume and volume of all books viewed.
The schematic diagram of the current composite structure is as follows:
Now you can easily get any category of books browsing volume and sales, such as access to science and technology books, you only need to call:
TechnicalStatistics.new.get_browse_count
And to get total sales of all books, you just need to call:
AllStatistics.new.get_sale_count
Of course, you can change the composition structure randomly, add various subcategories books, and the hierarchy of subcategories can be arbitrarily deep, as mentioned earlier, the expansion of the combined mode is very good.
Your leader tell you that the current he wrote this code is relatively high repetition, in fact, can be optimized, the redundant code are removed. Of course this task to you to do, your leader is busy people, long ran ran away.
Summarize
Advantages of Combinatorial mode:
can be flexible combination of local objects and the whole object of concern between the client, the local object and the whole object of the call no difference, make the call simple.
Disadvantages of Combinatorial mode:
1. The cost of combination operation is very high, if there are many child objects in an object tree, a simple call may crash the system;
2. The problem of object persistence, the combination pattern is a tree structure that is not good at saving data in relational databases, but it is ideal for XML persistence.
The applicable scenario for the combination mode:
1. Maintenance and presentation parts-overall relationship scenarios, such as tree menus, file and folder management.
2. From a whole can independently out part of the module or function of the scene.