Introduction to Composite pattern of Java design patterns

  • 2020-04-01 03:41:49
  • OfStack

Composite definition: objects are organized in a tree structure to achieve a "partial-whole" hierarchy, making the client consistent in its use of individual and Composite objects.

Composite is easy to understand. When you think of Composite, you should think of tree structure. All these objects in the Composite body have a common interface. When the method of an object is called and executed, the Composite iterates over the entire tree structure, looking for the object that also contains this method and realizes the call execution. Can be used to pull a hundred to describe.

So the Composite pattern USES the Iterator pattern, similar to the Chain of Responsibility pattern.

The Composite benefits:

1. Make the client call simple, the client can consistently use the composite structure or a single object, the user does not have to deal with a single object or the entire composite structure, which simplifies the client code.
2. It is easier to add object parts to the assembly body. The client does not have to change the code because a new object part is added.

How to use Composite

While other design patterns have few restrictions on defining interfaces, Composite has a rule that defines objects (or components) inside the interface to access and manage composites.

The following code is defined as an abstract class, usually using interface.


public abstract class Equipment{
 private String name;
 //Network price
 public abstract double netPrice();
 //Discount price
 public abstract double discountPrice();
 //Add part method
 public boolean add(Equipment equipment) { return false; }
 //Delete part method
 public boolean remove(Equipment equipment) { return false; }
 //Note that here, a widget method is provided for accessing a composite class. < br / >  public Iterator iter() { return null; }
 public Equipment(final String name) { this.name=name; }
}

The abstract Equipment class is the Component definition, which represents the objects in the assembly class, and several common methods are defined in Equipment.


public class Disk extends Equipment{
 public Disk(String name) { super(name); }
 //Define the Disk network price as 1
 public double netPrice() { return 1.; }
 //Defines the disk discount price to be 0.5 percent off. < br / >  public double discountPrice() { return .5; }
}

Disk is an object, or part, in a composite body that is a separate element (Primitive).

Another possibility is that a part is also an assembly, which means that there is a son underneath the part, which is the usual case in a tree, which should be easy to understand. Now we have to define this combination:


abstract class CompositeEquipment extends Equipment{
 private int i=0;
 //Define a Vector to hold 'son '
 private Lsit equipment=new ArrayList();
 public CompositeEquipment(String name) { super(name); }
 public boolean add(Equipment equipment) {
  this.equipment.add(equipment);
  return true;
 }
 public double netPrice(){
  double netPrice=0.;
  Iterator iter=equipment.iterator();
  for(iter.hasNext())
   netPrice+=((Equipment)iter.next()).netPrice();
  return netPrice;
 }
 public double discountPrice(){
  double discountPrice=0.;
  Iterator iter=equipment.iterator();
  for(iter.hasNext())
   discountPrice+=((Equipment)iter.next()).discountPrice();
  return discountPrice;
 }
 //Note here that this provides methods for accessing the parts in your assembly. < br / >  //DIsk is not present because dIsk is a separate (Primitive) element.
 public Iterator iter(){
  return equipment.iterator() ;
    }
    //Overloaded Iterator method
 public boolean hasNext() { return i<equipment.size(); }
 //Overloaded Iterator method
 public Object next(){
  if(hasNext())
   return equipment.elementAt(i++);
  else
     throw new NoSuchElementException();
 }
}

The above CompositeEquipment inherits Equipment, provides external access to its own objects, and overloads the Iterator, an interface to the Java Collection that is an implementation of the Iterator pattern.

Let's take a look at two concrete classes of CompositeEquipment: a Chassis and a Cabinet, which can hold a lot of things, such as baseplate, power box, hard disk box, etc. Inside the box can put some small equipment, such as hard disk floppy drive. There's no doubt that both of these are combinatorial.


public class Chassis extends CompositeEquipment{
 public Chassis(String name) { super(name); }
 public double netPrice() { return 1.+super.netPrice(); }
 public double discountPrice() { return .5+super.discountPrice(); }
} public class Cabinet extends CompositeEquipment{
 public Cabinet(String name) { super(name); }
 public double netPrice() { return 1.+super.netPrice(); }
 public double discountPrice() { return .5+super.discountPrice(); }
}

So far we have completed the architecture of the entire Composite pattern.

We can take a look at the client-side call to the Composote code:


Cabinet cabinet=new Cabinet("Tower"); Chassis chassis=new Chassis("PC Chassis");
//Load the PC concept into the Tower (load the tray into the box)
cabinet.add(chassis);
//Load a 10GB hard drive into a PC Chassis
chassis.add(new Disk("10 GB")); //Call the netPrice() method; < br / > System.out.println("netPrice="+cabinet.netPrice());
System.out.println("discountPrice="+cabinet.discountPrice());

The method called above, netPrice() or discountPrice(), actually Composite traverses the entire tree structure using Iterator, looking for objects that also contain this method and implementing the call execution.

Composite is a clever mode to reflect wisdom. In practice, if we encounter a tree structure, we can try to use this mode.

Take the forum as an example. There are many messages in one version of the forum, which have original posts and responses to the original posts. It is a typical tree structure.

Jive anatomy
In Jive, ForumThread is the container for ForumMessages. That is, ForumThread is similar to the compositeequipment. its relationship to messages is as follows:


[thread]
   |- [message]
   |- [message]
      |- [message]
      |- [message]
         |- [message]

In ForumThread, we see the following code:

public interface ForumThread {
 ....
 public void addMessage(ForumMessage parentMessage, ForumMessage newMessage)
   throws UnauthorizedException;
 public void deleteMessage(ForumMessage message)
   throws UnauthorizedException;
 public Iterator messages();
 ....
}

Similar to CompositeEquipment, it provides methods for accessing parts in your composition body: add, remove, and iterate.

In combination with the analysis of Jive in my other modes, we have a general understanding of the Jive forum architecture framework. If you don't understand the design patterns before, you can't read the Jive source code directly.


Related articles: