When should I use composite design pattern?
I don't understand when I should use composite design pattern. What kinds of benefits wil开发者_如何学Gol I get from this design pattern? I visited this website but it only tells me about the structure of the design pattern and not the scenarios in which it is used. I hope that it will be beneficial to the programmers like me who are starting to learn design pattern.
A Composite is a pattern that is useful anytime you may need to selectively treat a group of objects that are part of a hierarchy as "the same" when they are in fact different. Typically the examples used talk in terms of treating leaves and nodes the same, but the pattern can also be extended to heterogeneous lists.
For example, consider a doctor visit. When you go to a doctor various things happen, you usually see a nurse or an assistant first, they take your temperature, etc. Then the doctor performs an exam and makes diagnoses. Then the doctor may do some treatment, but often the nurse comes back to finish up. And different activities are performed during the visit. You have observations like weight and temperature. But a lab for example will be a different object because it often requires a sample which may then be sent out and require results to be recorded at a later date.
So we have software that allows recording all this and it will usually create some kind of hierarchy with nodes like:
Encounter:
PreExam
Exam
Treatment
and under each of these nodes you will have a variety of entries such as diagnosis, observation, lab procedure, diagnostic, injection, etc.
This is all well and good, and you end up with a structured, albeit very complex hierarchical record of the encounter.
Now suppose you need to generate billing. Suddenly you are faced with a very different requirement. Your medical record was required to create a very accurate picture of the encounter. In billing though you do not care who did what or in what order, in fact you really don't care what an activity is beyond a billing code. You simply want a single list of billable activities, i.e codes.
Not only is this information embedded in a record, that record is also very hard to traverse because it contains a large number of different objects. It is also variable in hierarchical structure - if you have a nail in your head they may skip any kind of pre-exam, or exam for that matter and go to treatment. If you go in to have stitches removed there may not be any pre exam or exam. A yearly physical has no treatment. etc etc. Very difficult to enumerate this sort of object graph.
A Composite pattern solves all this. You define a common interface or base class for all the objects. Let's call it "CareEntry". CareEntry has a property BillingCode. Now your Encounter can appear to be a simple container with nothing but CareEntry objects inside. Your billing service can now simply enumerate everything inside without having to worry about whether something is a node (PreExam, Exam) versus a leaf(weight temperature), or what node the object is in (PreExam Exam, etc) or what the actual type of the object is (lab, injection etc). Everything is also a CareEntry and treated uniformly - You simply enumerate all CareEntry objects in an Encounter and collect each one that has an non-null billing code and you are done. It is as simple as that.
Quoting from Design Patterns,
Use the Composite pattern when
- you want to represent part-whole hierarchies of objects.
- you want clients to be able to ignore the difference between compositions of objects and individual objects. Clients will treat all objects in the composite structure uniformly.
A common usage is the one used as a motivating example in the book, a display system of graphic windows which can contain other windows and graphic elements such as images, text. The composite can be composed at run-time, and the client code can manipulate all the elements without concern for which type it is for common operations such as drawing.
Composite Pattern lets clients to treat individual Objects as well compositions (of Individual Objects) uniformly.
For instance on double click of folder it should be open the folder. On double of file it should be opened in corresponding Program.
Operation is same but behaves based on whether it is Individual Objects or Compositions
Common Interface for individual Objects and Composite Objects
interface Data{
public void doubleClick();
}
Individual Object Implementation
class File implements Data {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void doubleClick() {
System.out.println(this.getName()+" file is Opened in a Program ");
}
}
Composite Implementation
class Folder implements Data {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private List<Data> folder = new ArrayList<Data>();
@Override
public void doubleClick() {
System.out.println(this.getName() + " folder is Opened");
for(Data data : folder) {
data.doubleClick();
}
}
public void add(Data data) {
folder.add(data);
}
public void remove(Data data) {
folder.remove(data);
}
}
Client Program
public class CompositePattern {
public static void main(String[] args) {
Folder f1 = new Folder();f1.setName("Folder 1");
Folder f2 = new Folder();f2.setName("Folder 2");
Folder f3 = new Folder();f3.setName("Folder 3");
File file1 = new File();file1.setName("File 1");
File file2 = new File();file2.setName("File 2");
File file3 = new File();file3.setName("File 3");
File file4 = new File();file4.setName("File 4");
f1.add(file1);
f2.add(file2);
f3.add(f2);
f3.add(file3);
f3.add(file4);
f1.doubleClick();f2.doubleClick();f3.doubleClick();
}
}
I often use Composite design pattern to hide collections. In many cases we work with collections in exactly the same way when there are many elements and when there is only one element in them.
That is the problem, because the class containing a collection then swarms with foreach loops that basically do the same thing - walk through all elements and apply some aggregate function.
To resolve the issue, I introduce an interface which is implemented by the single element as well as the class hiding the collection of those elements. The purpose of the composite class is then to contain all the aggregate functions that used to be in the client class.
You can find some useful examples in this article: Working With Collections
Common thing here is that Composite is not necessarily representing the part-whole relationship. It is possible to introduce composite element just to move the loops out of the client.
And here is one by-the-book example of applying the Composite pattern to hide parts behind the composite element: Composite Design Pattern
Having recently studied and tried my hand at it, I recognized one powerful concept to keep in mind about Composites.
Composites hide the complexity involved in the collections, i.e. looping through them, sorting them out, filtering some etc. and allows you to treat it as if it is a single organism.
Say, you have a dog at one kennel and many dogs at another. You want to feed them and vaccinate them but you cannot feed them if they ate within an hour or feed them if they were vaccinated in the last five hours, or vaccinate them if they vomited etc.
More importantly, there are rules of packing order where dog breed A eats before breed B, unless breed C dog was around and barking to the top of his lungs.
This will quickly reach to a point where you simply don't want to care about anything but just call a helper and tell him to feed 'all dogs'. Or better, three helpers to keep track of feeding, vaccination and vomiting, barking and packing and all other awesome stuff.
By calling out helpers, you relied on the Composition pattern. You just go and 'feed' each kennel, be it one dog or a ten. You just want the kennel full of dogs to sort it out themselves and figure out how they feed, because you have too much in your hands at the cashier.
So, for you, a Dog is an IDog, who Feed(), Bark(), Vomit() and GetVaccine(). A Kennel is also a Dog, who you call kennel.Feed(). You are done. The Kennel kennel has to figure out what to do now internally. It may have a time keeping mechanism to follow each dog's feeding and other bodily function times. It is all encapsulated neatly.
You may find it being-a-must when you will be working with binary trees
or other complex data structures like list of lists of lists
- etc... then, when every element (class) implements 1 interface, you can do the same methods on 1 leaf or on whole group of them - copping, adding, removing, moving... whatever, what you have implemented correctly. It's very useful and simple.
The answer should be -
Compose objects into tree structures to represent whole-part hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
- Recursive composition
- “Directories contain entries, each of which could be a directory.”
- 1-to-many “has a” up the “is a” hierarchy
copied from a forum.
Composite design pattern real world example, When we have chances of having instance of same parent type inside or component type.
Example: In foreign exchange trading systems Ex1
You might have a cross currency pair (AUD/EUR)= (AUD/USD and 1/(EUR/USD)) the point here is your Instrument(Cross) can have two Instruments(Direct) inside.
In another example have
One Instrument(Cross) and Instrument(Direct) and Instrument(Cross) which can be further divided in to tow Instrument(Direct). SGD/CZK = USD/SGD (Direct) and USD/CZK (Cross) = USD/SGD (Direct) and (1/EUR/USD)(Direct) and EUR/CZK(Direct)
The point here is you keep dividing until you don't find all direct currency pairs.
Above can be easily implemented using Composite Design pattern.
Hope this simple example helps
http://msdn.microsoft.com/en-us/magazine/cc301852.aspx
Composite Pattern in ASP.NET
And, well known Composite UI Application Block is based on Composite Pattern.
if you want to build nested similar object means you can go for composite design pattern eg: in realtime if you want to show tree structure for the office employee based on hierarchy
Take one basic example of an organisation where hierarchy of employees is defined like engineer, manager, head.
Now let’s say you want to implement method to print all employees for a given type. For example head will have managers and managers will have engineers.
Please make a note that composite pattern violates the SOLID principles because some of the methods could be meaningful for managers (like DoAppraisal) but not for the engineers.
精彩评论