Question

I have a functional AdjacencyListGraph class that adheres to a defined interface GraphStructure. In order to layer limitations on this (eg. acyclic, non-null, unique vertex data etc.), I can see two possible routes, each making use of the GraphStructure interface:

  1. Create a single class ("ControlledGraph") that has a set of bitflags specifying various possible limitations. Handle all limitations in this class. Update the class if new limitation requirements become apparent.

  2. Use the decorator pattern (DI, essentially) to create a separate class implementation for each individual limitation that a client class may wish to use. The benefit here is that we are adhering to the Single Responsibility Principle.

I would lean toward the latter, but by Jove!, I hate the decorator Pattern. It is the epitome of clutter, IMO. Truthfully it all depends on how many decorators might be applied in the worst case -- in mine so far, the count is seven (the number of discrete limitations I've recognised at this stage). The other problem with decorator is that I'm going to have to do interface method wrapping in every... single... decorator class. Bah.

Which would you go for, if either? Or, if you can suggest some more elegant solution, that would be welcome.

EDIT: It occurs to me that using the proposed ControlledGraph class with the strategy pattern may help here... some sort of template method / functors setup, with individual bits applying separate controls in the various graph-canonical interface methods. Or am I losing the plot?

Was it helpful?

Solution

Ah, I see it now. The strategy pattern in a ControlledGraph class is indeed the way to go.

Each limitation is a discrete strategy class. Each of these implements the entire GraphStructure interface, although most methods will be left empty (eg. an acyclic limitation is only interested in using addEdge() to prevent cycle insertions, others methods will be left empty).

Each time the ControlledGraph has one of its interface methods called, it will call the matching methods of each of the strategies/limitations it contains. It may hold only one of each type of strategy, obviously.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top