[Design mode] study note 13: Composite)

Source: Internet
Author: User

From http://blog.csdn.net/shuangde800

Cognition Combination Mode


In the previous article, we can use an iterator to traverse a set (array, arraylist, vector, hashtable, etc ).

Suppose there is such a collection structure I: There is a menu in the restaurant, and there is a sub menu in the menu, which is actually a tree structure.


Then, the previous iterator cannot be used.


We need a new design:

1. A tree structure is required to accommodate menus, submenus, and menu items.

2. You must be sure that you can walk between items in each menu, and at least as convenient as using the iterator now.

3. We also need to move between menus more elastically. For example, you may only need to traverse the dessert menu, or you can traverse the entire menu of the restaurant.


Define a combination mode

The combination mode allows you to combine objects into a tree structure to express the "whole/part" hierarchy. Combination allows customers to process individual objects and object combinations in a consistent manner.


Sometimes it is also called the partial-overall mode, which makes the concept of simple elements and complex elements blurred in the tree structure problem. The customer program can process complex elements like simple elements, this decouples the customer program from the internal structure of complex elements.


The combination mode allows you to optimize the processing of recursive or hierarchical data structures. There are many examples of hierarchical data structures, making the combination mode very useful. A general example of hierarchical data structure is what you encounter every time you use a computer: a file system. The file system consists of directories and files. Content can be installed in each directory. The contents of a directory can be files or directories. In this way, computer file systems are organized in recursive structures. If you want to describe such a data structure, you can use the composite mode.


Taking nested menus as an example, this mode can create a tree structure to process nested menus and menu item Groups in the same structure. By placing menus and items in the same structure, we create a "whole/part" hierarchy, that is, an object tree consisting of menus and menu items. However, it can be regarded as a whole, such as a rich menu.

Once there is a rich "big menu", we can use this mode to"Unified processing of individual objects and composite objects".


This means that if we have a menu with a tree structure, the sub-menu and a sub-menu that may also contain a menu item, then any menu is a "Combination ". Because it can contain both other menus and menu items. We can ignore the differences between object combinations and individual objects.


In combination mode, you only need to write simple code to apply the same operation to the entire menu structure!







Use combination to design menus

1. Implement menu Components

// The abstract class of the menu component // The Role Of The Menu component is to provide a common interface for the leaf node and the combination node // All components must implement the menucomponent interface // but the leaf node and the roles of the combined nodes are different, therefore, some methods may not be suitable for some nodes. It is best to throw a runtime exception public abstract class menucomponent {public void add (menucomponent) {Throw new unsupportedoperationexception ();} public void remove (menucomponent) {Throw new unsupportedoperationexception ();} public menucomponent getchild (int I) {Throw new unsupportedoperationexception ();} Public String getname () {Throw new unsupportedoperationexception ();} Public String getdescription () {Throw new unsupportedoperationexception ();} public double getprice () {Throw new unsupportedoperationexception ();} public Boolean isvegetarian () {Throw new unsupportedoperationexception ();} public void print () {Throw new unsupportedoperationexception ();}}

2. Implement menu items

// This is the leaf class of the composite class diagram. Here it is the menu item public class menuitem extends menucomponent {string name; string description; Boolean vegetarian; double price; Public menuitem (string name, string description, boolean vegetarian, double price) {This. name = Name; this. description = description; this. vegetarian = vegetarian; this. price = price;} Public String getname () {return name;} Public String getdescription () {return description;} public double getprice () {return price;} public Boolean isvegetarian () {return vegetarian;} // This is different from the previous implementation. // We overwrite the print () method. // For the menu item, this method prints the complete menu entry // including name, description, price, and other public void print () {system. out. print ("" + getname (); If (isvegetarian () {system. out. print ("(v)");} system. out. println ("," + getprice (); system. out. println ("--" + getdescription ());}}

3. Implement a menu combination

Public Class Menu extends menucomponent {// The menu can have any number of sons // and these sons must belong to the menucomonent type // record them in the internal arraylist menucomponents = new arraylist (); string name; string description; // different from the menu item. Only the public menu (string name, string description) {This. name = Name; this. description = description;} // Add a sub menu or menu item public void add (menucomponent) {menucomponents. add (menucomponent);} // delete a sub-menu or menu item public void remove (menucomponent) {menucomponents. remove (menucomponent);} // get a son node public menucomponent getchild (int I) {return (menucomponent) menucomponents. get (I);} Public String getname () {return name;} Public String getdescription () {return description;} // recursively print the menu public void print () {system. out. print ("\ n" + getname (); system. out. println ("," + getdescription (); system. out. println ("---------------------"); iterator = menucomponents. iterator (); While (iterator. hasnext () {menucomponent = (menucomponent) iterator. next (); menucomponent. print ();}}}


Combined iterator

The iterator in the combination mode needs to be implemented using recursion.

Public class compositeiterator implements iterator {stack = new stack (); // import the iterator of the top-level combination that we need to traverse into a stack data structure. Public compositeiterator (iterator) {stack. push (iterator);} // when the customer wants to obtain the next element, // we call hashnext () to determine whether there is another public object next () element () {If (hasnext () {iterator = (iterator) stack. peek (); menucomponent Component = (menucomponent) iterator. next (); If (Component instanceof menu) {// If the element is a menu, we have another combination that needs to be included in the traversal. // put it into the stack. push (component. createiterator ();} return component;} else {return NULL;} public Boolean hasnext () {If (stack. empty () {// If the stack is empty, return false is missing;} else {iterator = (iterator) stack. peek (); If (! Iterator. hasnext () {stack. pop (); Return hasnext () ;}else {return true ;}}// deletion of Public void remove () {Throw new unsupportedoperationexception () ;}} is not supported ();}}

An empty iterator requires a composite iterator. The createiterator () method must be added to each component.


Implement the following in the menu:
Public Class Menu extends menucomponent {// other part of the Code do not need to modify public iterator createiterator () {return New compositeiterator (menucomponents. iterator ());}}

But how to implement it in the menu item? We know that the menu item is a leaf node and there is nothing to traverse.

There are two options: Select 1: If null is returned, we can let the createitrerator () method return NULL. However, if so, our Customer Code requires a Condition Statement to determine whether the return value is null. Select 2: Return an iterator. The hasnext () of this iterator always returns false. This method is obviously better, so you don't have to worry about whether it is null.
public class NullIterator implements Iterator {   public Object next() {return null;}  public boolean hasNext() {return false;}   public void remove() {throw new UnsupportedOperationException();}}

Createiterator () method for menu items

Public class menuitem extends menucomponent {// other part of the Code do not need to be modified public iterator createiterator () {return New nulliterator (); // return NULL iterator }}


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.