Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is transparency valued over safety in the Composite pattern?

Tags:

I have just learned about the Composite pattern. As I understand, the main idea behind it is to treat both edges and nodes of a tree uniformly. This means that the "transparency" of the structure is valued more than the "safety", leading us to something like this:

enter image description here

I understand the concept, but can't think of situations when sacrificing safety for transparency would be a good choice to make. In other words, in which cases do we need transparency so badly that we are willing to make such a serious sacrifice?

like image 303
Alex Lomia Avatar asked Apr 03 '16 10:04

Alex Lomia


1 Answers

It would be more accurate to say that transparency is valued over safety in some discussions of the Composite pattern, including the original description by the Gang of Four. But the Gang of Four description recognizes the tradeoff, and other influential discussions are more pro-safety. Anyway, here's the case for transparency:

Safety (declaring methods not applicable to Leaf only in Composite) has costs:

  • The client of a tree of safe Components needs to check whether each Component is a Composite as it traverses the tree (possibly using the external polymorphism technique shown on page 168 of the GoF book). Either every client of the tree needs to implement this checking or, if the checking is provided in a Visitor or some such, needs to deal with that complexity.

  • Component implementers need to choose whether each component is a Leaf or Composite, and change their code if they change their choice.

The value of 'transparency' (uniformity of Leaf and Composite, i.e. declaring all tree-manipulation methods in Component) is that the cost of safety is minimized.

Transparency becomes more valuable if any of the following are true:

  • Leafs are rare or nonexistent. For example, in a UI toolkit, it might be possible to add children to any component (even a component which normally has little use for children, like a checkbox) and expect them to be rendered intelligently. The visual flexibility thus provided might be worth the extra effort required of developers of what would otherwise be Leafs, and a default implementation in Component might minimize that extra effort.

  • Many uses of the tree don't need to distinguish between Leafs and Composites. For example, again in a UI toolkit, operations like drawing could treat Leafs and Composites uniformly by iterating over each Component's possibly zero-length list of children.

  • The runtime (memory and CPU) cost of every Component having a list of children is low relative to the rest of the program.

If the above are true, uniformity pays off more: clients of the tree need to do less to use the tree, and situations where that ease of use gets clients in to trouble are rare. This may often be the case with UI components: the only time when a client of the tree needs to worry about whether something is a Composite or not may be when they're constructing (adding to) the tree, at which time they know what all of the concrete Components are anyway.

Java Swing made this choice: JComponent includes add methods. Developers just need to not use them with JComponents that don't accommodate children, which is obvious for many components (again, such as checkboxes).

If any of the opposite situations are the case then distinguishing between Leafs and Composites becomes more valuable and the increased complexity of managing a safe tree becomes worthwhile. If Leafs are common and/or many clients of the tree do need to distinguish between Leafs and Composites, but the types are 'transparent' and don't enable the distinction (perhaps the GoF should have called this choice opaque rather than transparent), then it's more likely that a client will make a mistake. If lists of children are too expensive, then it's worth making Component implementors choose whether each component is a Leaf or Composite.

like image 77
Dave Schweisguth Avatar answered Sep 28 '22 03:09

Dave Schweisguth