Design Pattern 16-Composite)

Source: Internet
Author: User
1. Scenario Simulation

Use software to simulate the root and branch nodes and leaf nodes of a big tree
Abstract: Container nodes and leaf nodes
2. No mode solution

Package demo14.composite. example1; import Java. util. *;/*** combination object, you can include other composite objects or leaf objects */public class composite {/*** to record other composite objects contained */private collection <composite> childcomposite = new arraylist <composite> (); /*** used to record other contained leaf objects */private collection <leaf> childleaf = new arraylist <leaf> (); /*** name of the composite object */private string name = "";/*** constructor, input the name of the composite object * @ Param name the name of the composite object */Public composite (string name) {This. name = Name;}/*** add other composite objects it contains to the composite object * @ Param c Other composite objects it contains */Public void addcomposite (composite C) {This. childcomposite. add (c);}/*** Add the leaf object it contains to the composite object * @ Param leaf the leaf object it contains */Public void addleaf (leaf) {This. childleaf. add (leaf);}/*** output the structure of the composite object * @ Param prestr prefix, which is mainly a space spliced by level, implement backward indent */Public void printstruct (string prestr) {// output it to system first. out. println (prestr + "+" + this. name); // then add a space, indicating to indent a space backward, and output the leaf object prestr + = ""; for (leaf: childleaf) {leaf. printstruct (prestr);} // output the child object of the current object for (composite C: childcomposite) {// recursively output each child object C. printstruct (prestr );}}} **************************************** **************************************** * ************** package demo14.composite. example1;/*** leaf object */public class leaf {/*** name of the leaf object */private string name = "";/*** constructor, input the name of the leaf object * @ Param name the name of the leaf object */Public leaf (string name) {This. name = Name;}/*** structure of the output leaf object. The leaf object has no sub-object, that is, the name of the output leaf object * @ Param prestr, it is mainly based on the space spliced by level to realize backward indent */Public void printstruct (string prestr) {system. out. println (prestr + "-" + name );}} **************************************** **************************************** * ****************** package demo14.composite. example1; public class client {public static void main (string [] ARGs) {// define all composite object composite root = new composite ("clothing "); composite C1 = new composite ("men's wear"); composite C2 = new composite ("Women's Wear"); // define all leaf objects leaf leaf1 = new leaf ("shirt "); leaf leaf2 = new leaf ("jacket"); leaf leaf3 = new leaf ("skirt"); leaf leaf4 = new leaf ("set "); // combine the combination object and leaf object root according to the tree structure. addcomposite (C1); root. addcomposite (C2); c1.addleaf (leaf1); c1.addleaf (leaf2); c2.addleaf (leaf3); c2.addleaf (leaf4); // call the output function of the root object to output the entire tree root. printstruct ("");}}
3. Problem

You can easily find out a problem: You must distinguish between leaf nodes and container nodes, both on the client side and on the internal side, so that the program becomes complex, it is not convenient for function expansion, and we need to know two classes. Can we integrate them into one class so that the client can display the following information? The answer is yes.

Package demo14.composite. example2; public class client {public static void main (string [] ARGs) {// defines multiple composite objects component root = new composite (); component C1 = new composite (); component C2 = new composite (); // defines multiple leaf Objects component leaf1 = new leaf (); component leaf2 = new leaf (); component leaf3 = new leaf (); // group and create a tree-like object structure root. addchild (C1); root. addchild (C2); root. addchild (leaf1); c1.addchild (leaf2); c2.addchild (leaf3); // operate the component object component o = root. getchildren (1); system. out. println (o );}}
4. Sample Code of the Solution

Obviously, the above client code is much more pleasing to the eye, so how can we implement it?
4.1 first look at the structure chart

 
4.2 definition of combined modes

Combine objects into a tree structure to represent the "part-whole" hierarchy. The combination mode ensures consistency between the use of a single object and a composite object.
4.3 Sample Code:

Package demo14.composite. example2;/*** abstract Component Object: declares an interface for the object in the combination to implement the default behavior of the interface */public abstract class component {/*** probe method, possible functional methods of child component objects */public abstract void someoperation (); /*** Add a component object to a composite object ** @ Param child * The component object added to the composite object */Public void addchild (Component child) {// default implementation, throw an exception because the leaf object does not have this function, or the child component does not implement this function. Throw new unsupportedoperationexception ("the object does not support this function ");} /*** remove a component object from a composite object ** @ Param child * Object */Public void removechild (Component child) {// default implementation, throwing an exception because the leaf object does not have this function, or the sub-component does not implement this function. Throw new unsupportedoperationexception ("the object does not support this function ");} /*** return the index of the component object corresponding to an index ** @ Param Index, the index starts from 0 * @ return the component object corresponding to the Index */public component getchildren (INT index) {// default implementation. An exception is thrown because the leaf object does not have this function, or the sub-component does not implement this function. Throw new unsupportedoperationexception ("the object does not support this function ");}} **************************************** * * **************************** Package demo14.composite. example2; import Java. util. *;/*** composite object. It usually needs to store sub-objects and define the behavior of Parts with sub-parts, * perform operations related to sub-parts defined in component */public class composite extends component {/*** to store sub-component objects contained in a composite object */private list <component> childcomponents = NULL; /*** indicates the method, which usually requires recursive calling */Public void someoperation () {If (childcomponents! = NULL) {for (component C: childcomponents) {// recursively call C. someoperation () ;}} public void addchild (Component child) {// delayed initialization if (childcomponents = NULL) {childcomponents = new arraylist <component> ();} childcomponents. add (child);} public void removechild (Component child) {If (childcomponents! = NULL) {childcomponents. Remove (child) ;}} public component getchildren (INT index) {If (childcomponents! = NULL) {If (index> = 0 & index <childcomponents. size () {return childcomponents. get (INDEX) ;}} return NULL ;}} **************************************** * ***************************** package demo14.composite. example2;/*** leaf object, which no longer contains other sub-objects */public class leaf extends component, the leaf object may have its own function method */Public void someoperation () {// do something }}********************************* * *********************************** package demo14.composite. example2; public class client {public static void main (string [] ARGs) {// defines multiple composite objects component root = new composite (); component C1 = new composite (); component C2 = new composite (); // defines multiple leaf Objects component leaf1 = new leaf (); component leaf2 = new leaf (); component leaf3 = new leaf (); // group and create a tree-like object structure root. addchild (C1); root. addchild (C2); root. addchild (leaf1); c1.addchild (leaf2); c2.addchild (leaf3); // operate the component object component o = root. getchildren (1); system. out. println (o );}}
5. Combined Mode solution Scenario Simulation

The amount of code modifications is not large, which is similar to that of the sample code.
5.1 structure:

 
5.2 The Code is as follows (basically the same as the sample code, but I will not introduce it much, and the comments are very clear)

Package demo14.composite. example3;/*** abstract component object */public abstract class component {/*** name of the output component */public abstract void printstruct (string prestr ); /*** Add a component object to a composite object ** @ Param child * The component object added to the composite object */Public void addchild (Component child) {// default implementation, throw an exception because the leaf object does not have this function, or the child component does not implement this function. Throw new unsupportedoperationexception ("the object does not support this function ");} /*** remove a component object from a composite object ** @ Param child * The removed component object */Public void re Movechild (Component child) {// default implementation, throwing an exception because the leaf object does not have this function, or the sub-component does not implement this function. Throw new unsupportedoperationexception ("the object does not support this function ");} /*** return the index of the component object corresponding to an index ** @ Param Index, the index starts from 0 * @ return the component object corresponding to the Index */public component getchildren (INT index) {// default implementation. An exception is thrown because the leaf object does not have this function, or the sub-component does not implement this function. Throw new unsupportedoperationexception ("the object does not support this function ");}} **************************************** ********************* * ******************************* Package demo14.composite. example3; import Java. util. *;/*** combination object, other composite objects or leaf objects */public class composite extends component {/*** can be used to store child component objects contained in a composite object */private list <component> childcomponents = NULL; /*** name of the composite object */private string name = "";/*** constructor, input the name of the composite object * @ Param name the name of the composite object */Public composite (string name) {This. name = Name;} public void addchild (Component child) {// Delayed initialization if (childcomponents = NULL) {childcomponents = new arraylist <component> ();} childcomponents. add (child);}/*** output the structure of the composite object * @ Param prestr prefix, which is mainly a space spliced by level, implement backward indent */Public void printstruct (string prestr) {// output it to system first. out. println (prestr + "+" + this. name); // if the child widget contains child widgets, the object if (this. childcomponents! = NULL) {// Add a space to indent the space prestr + = ""; // output the child object of the current object for (component C: childcomponents) {// recursively output each sub-Object C. printstruct (prestr );}}}} **************************************** **************************************** * ************* package demo14.composite. example3;/***** leaf object */public class leaf extends component {/***** leaf object name */private string name = "";/*** constructor, input the name of the leaf object ** @ Param name * Name of the leaf object */Public leaf (string name) {This. name = Name;}/*** structure of the output leaf object. The leaf object has no sub-object, that is, the name of the output leaf object ** @ Param prestr * prefix, it is mainly based on the space spliced by level to realize backward indent */Public void printstruct (string prestr) {system. out. println (prestr + "-" + name );}} **************************************** **************************************** * *********** package demo14.composite. example3; public class client {public static void main (string [] ARGs) {// define all composite objects component root = new composite ("clothing "); component C1 = new composite ("men's wear"); component C2 = new composite ("Women's Wear"); // define all the leaf Objects component leaf1 = new leaf ("shirt "); component leaf2 = new leaf ("jacket"); component leaf3 = new leaf ("skirt"); component leaf4 = new leaf ("set "); // combine the combination object and leaf object root according to the tree structure. addchild (C1); root. addchild (C2); c1.addchild (leaf1); c1.addchild (leaf2); c2.addchild (leaf3); c2.addchild (leaf4); // call the output function of the root object to output the entire tree root. printstruct ("");}}
6. Explanation of the combination mode 6.1 Key Points

Objective: The client no longer distinguishes between leaf nodes and composite objects
Key Point: design an abstract composite object
6.2 essence of the Combination Model

Unified leaf object and composite object

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.