I'm trying to figure out a class design for a library that operates on a weighted graph. Various algorithms may be performed on this graph, for example, finding the shortest distance between two nodes, the longest distance between two nodes, the number of paths of between two nodes where the distance is less than 10 (say), etc.
My concern is NOT how to implement the algorithm or the data structures for the graphs as I know how to do this, rather it is on the overall high-level class design. The point being that in the future we may want to add other algorithms, so the solution should be easily extensible. One option for implementing is just to write a single class that has methods for implementing each of these algorithms. Then in the future additional methods can be added to this class for any new algorithms.
public class GraphCalculator
{
Graph _graph;
public int GetLongestDistance(string startPlaceName, string endPlaceName)
{
}
public int GetShortestDistance(string startPlaceName, string endPlaceName)
{
}
public int GetNumberOfPaths(int minimumDistance)
{
}
//any new algorithms will be implemented as new methods added to this class
}
My concern is that this violates the SOLID Open/Closed principle. Should each algorithm instead be implemented in its own class? If so, what is the recommended class structure to achieve this, so that it is loosely coupled and easily testable, and how would it be called from the public API layer? Are there any recommended design patterns for this?
The answer to your question Should each algorithm instead be implemented in its own class is definitely yes! You are stating, that you want easily extensible solution. A single class that has methods for implementing each of these algorithms. Then in the future additional methods can be added to this class for any new algorithms. it not extensible at all! Your are changing the code and you need to modify your current base implementation! This is exactly the opposite of the OOP principle - closed for modification, but open for extension!
Every single algorithm you have to implement (at present or in future) is a behaviour and should be defined using an interface. All implementations should implement this common interface. This way you will also be able to test every single algorithm implementation easily on its own. This allows you also to define one list of algorithms, that is easily maintained dynamically (via code or configuration). Considering all this, what you need is some kind of a plug-in architecture.
One design pattern that matches your need could be the Visitor pattern, since it adds new operations (= algorithms like shortest path, longest path, etc.) to existing data structures (graph object).
Another option could be the PlugIn design pattern, although IMO this pattern could be more challenging to implement than the visitor. If it is alright to use 3th party software and existing frameworks, you could have a look at the Sprint plugin project, that uses the Spring framework and defines a pluggable architecture helper. A (somewhat) similar solution for .NET is the Managed Extensibility Framework and/or the Enterprise Library - Unity Application Block.
Why does it have to it's own class to begin with? It doesn'T do anything useful on it's own, just wrapping the Graph instance and up to know all it does offer are functions over an Graph. Have you considered making them static functions in a helper class where all relevant parameters are passed into instead?
Or you might consider the Strategy Pattern if you want to make the implementations interchangable.
Related
I've been learning about design patterns and I think I'm a little bit stuck with an exercise where I do not posses any answer-pages to.
I already used the strategy pattern to create this:
http://i.imgur.com/5Lia4JD.png (minus the setBehavior functions in duck)
I need to improve this design with simple factory because at the moment, the 2 types of behaviors are instantiated via following code (shown via example):
public MallardDuck()
{
setQuackBehavior(new Quack());
setFlyBehavior(new FlyWithWings());
}
This is not correct because we need to program to an interface and not to an implementation.
What I thought to do is making 2 separate factories that each handle a specific behavior but when I made the design I started doubting my solution. Is it normal to do this sort of thing with simple factory?
Could anyone push me in the correct direction? :]
If you're programming Ducks, then it's a toy example anyway. Go ahead and do the two separate simple factories. The general rule is a simple factory per interface. You could put all the simple factories in one class to make it less complex.
The disadvantage of concrete classes instantiating other concrete classes is of course the risky coupling to implementations. If the implementation details change (yes, the new is trivial but the whole ducks example is trivial), your classes that know that information are also liable to change.
You're right that it's not programming to an interface. Classes that know less about implementation details are more insulated from changes in those details, which is the whole point of using interfaces.
If you want to avoid the strong coupling between concrete strategies and their host you may rely on a factory that knows how to instantiate a Duck with the proper strategies for a given type rater than having a concrete class per type.
The above design may be slightly more testable, but I do not think you should be too concerned about the coupling between concrete ducks and the concrete strategies they use.
This is not correct because we need to program to an interface and not to an implementation.
And you program to an interface since setQuackBehavior() takes as input an interface and that your quack class represents the quack behavior field as an interface and not an implementation.
At a time, in a code, using a implementation class is normal.
Using a factory with methods returning based interface instances is useful in many cases but in your case, I don't see the interest. Why your quack subclasses should not know which concrete behavior used ?
If it has no reason, so it seems ok :
setQuackBehavior(new Quack());
Using factory with not added value gives a complex code without reasons.
I know this is a question that has been asked a 100 times over but I would like to provide some of my own definitions to see if I understand an interface correctly.
Questions:
What is an interface?
An interface defines the structure for code design. An interface lays the foundation for your design and is made up of a collection of abstract methods and contains behaviors that a class must implement.
When to use an interface?
When similar methods of a design are to be reused across a project. This creates the structure of the behavior within a a project.
Why use an interface?
You use an interface in a project to create the foundation much like the construction of a new home. When a new home is built the frame is built, then the walls and doors and so on are added.
My above answers are what I describe as an interface and would like to know whether I am correct or not? If not, then please explain?
Thanks
You use an interface so that any class can make use of it as long as they implement it. That is why List is so cool and we use it in everyday programming.
Cows and Goats are both animals and they eat, walk, sleep, etc. You do not want to declare the same behaviors separately. If you now have a new animal, you will have to define the similar behaviors again. An interface forces you to implement the required behaviors.
I would argue that an interface is more like a an optional contract -- you specify the method names, parameters, and return type, and if a class chooses to implement the interface, it must then conform to the terms of that contract. It's more like an API spec than a design foundation, as interfaces are relatively flexible.
Note that this flexibility gives you considerable leeway in how you choose to use interfaces. As long as the implementing class provides the agreed-upon methods, the implementation is entirely up to you. There are interfaces (e.g. Serializable) that require no methods, and simply act as markers for the programmer's intent regarding a certain class.
Another use of interfaces is to mitigate the disadvantages of the fact that Java doesn't support multiple inheritance. Though each implementing class must contain the actual code, you might use an interface in an 'inheritance-like' way, to indicate that a certain set of classes derives behavior (in name, if not necessarily in implementation) from some common, more abstract pattern.
I would definitely suggest looking through the javadocs (perhaps the Collections framework) for more examples of interfaces. To continue with the contract analogy, the main use of interfaces is as a sort of API that specifies behavior you can count on, without having to know the implementation details.
The problem with the home analogy is that it's too restrictive-- interfaces don't restrict the design of a class as much as a foundation prescribes a certain structure for a building. Additionally, a building can only have one foundation, and in Java, there is no limit to the number of interfaces a class may implement.
Think of a TV remote analogy.
What
Its a standard way of using a Television(any television...flat screen, CRT, LED, LCD, Plasma etc).
So its basically an interface to a Television. Now, all TV remotes must have some basic common buttons (On, Off, Vol+, Vol-, Ch+, Ch-), these are the methods which should be present in the interface. Different brands implement these using different techs.
When
Now all Television brands want to share this standard way of controlling a Television (which is a big complicated machine).
Why
Think about it. It helps the consumer. As far as the consumer is concerned, he/she does not need to know how to manually operate the Television or from inside(you can do that from the circuit board!)
I'm studying the visitor pattern and I wonder how this pattern is related to the open/closed principle. I read on several websites that "It is one way to follow the open/closed principle." (citated from wikipedia).
On another website I learned that is follows the open/closed principle in such a way that it is easy to add new visitors to your program in order to "extend existing funcionality without changing existing code". That same website mentions that this visitor pattern has a major drawback: "If a new visitable object is added to the framework structure all the implemented visitors need to be modified." A solution for this problem is provided by using Java's Reflection framework.
Now, isn't this solution a bit of a hack solution? I mean, I found this solution on some other blogs as well, but the code looks more like a workaround!
Is there another solution to this problem of adding new visitables to an existing implementation of the visitor pattern?
Visitor is one of the most boilerplate-ridden patterns of all and has the drawbacks regarding non-extensibility that you mention. It is itself a sloppy workaround to introduce double dispatch into a single-dispatch language. When you consider all its drawbacks, resorting to reflection is not such a terrible choice.
In fact, reflection is not a very bad choice in any case: consider how much today's code is written in dynamic languages, in other words using nothing but reflection, and the applications don't fall apart because of it.
Type safety has its merits, certainly, but when you find yourself hitting the wall of static typing and single dispatch, embrace reflection without remorse. Note also that, with proper caching of Method objects, reflective method invocation is almost as fast as static invocation.
It depends on precisely what job the Visitor is supposed to accomplish, but in most cases, this is what interfaces are for. Consider a SortedSet; the implementation needs to be able to compare the different objects in the set to know their ordering, but it doesn't need to understand anything else about the objects. The solution (for sorting by natural order) is to use the Comparable interface.
I have a polymorphism structure in my project, and thinking of if it could be valuable to rewrite it to use Visitor Pattern.
The basic structure is: I have some drawing objects (Rectangle, Ellipse, Line, more to come) that have of course some behavior in common. The behavior is defined by the interface Drawable.
So far, dragging should always behave the same, but drawing them selected should differ.
I therefore introduced the abstract Figure class, which already implements drag(), but delegates the implementation of drawSelected() to the extending classes.
Of course the interface will later be extended with additional functions I need, and also additional implementations of Figures will come.
Now my question: Would your rather stick to this design, or switch to Visitor. And if so, why?
Especially I'm not sure if my present approach is good to have the logic/algorithms for drawing selections inside the objects itself.
interface Drawable {
void drag();
void drawSelected();
}
abstract class Figure implements Drawable {
protected int x, y, w, h;
#Override
void drag() {
//implementation always the same for different figures
}
}
class Rectangle extends Figure {
#Override
drawSelected() {
//draw a dashed rectangle around this object
}
}
class Ellipse extends Figure {
#Override
drawSelected() {
//draw a dashed ellipse around this object
}
}
class Line extends Figure {
#Override
drawSelected() {
//draw the line itself dashed
}
}
The problem you have requires using object structures that are unlikely to change over time; there may be new structures (figures) that may get added but a given object structure (figure) is unlikely to change. Though the structures might not change, you may add more and more operations on the structures and these operations may or may not be common across structures. I think these things make a use-case for using the Visitor pattern.
To elaborate further, consider the scenario where you are adding a new operation where you require one implementation for one group of figures, another implementation for another group and so on. In current design, you may be able to have only one common implementation in the abstract class (unless you use instanceOf, but that again is not considered a good practice) and would have to override that implementation in each of the other classes. Where as in case of using the Visitor pattern, you would always call the visit method (that would be bound at runtime) and within that you can decide which implementation to call.
In the current design, you may also reach a situation where you have common logic lying in different classes. But in Visitorpattern, you can maintain various implementations within the visitor class and reuse them in the visit method, so no code duplication.
Visitorpattern would also give you ease of switching a given figure from one implementation to the other, if required.
Though on adding new classes, you would need to add new implementations to the visitor interface, it will not impact any of you existing classes (figures) or their implementation.
Looking at the usages of the Visitor pattern that is from GoF seems that using that pattern in your case is inappropriate.
Usages
an object structure contains many classes of objects with differing interfaces, and you want to perform operations on these objects that
depend on their concrete classes.
many distinct and unrelated operations need to be performed on objects in an object structure, and you want to avoid "polluting"
their classes with these operations. Visitor lets you keep related
operations together by defining them in one class. When the object
structure is shared by many applications, use Visitor to put
operations in just those applications that need them.
the classes defining the object structure rarely change, but you often want to define new operations over the structure. Changing the
object structure classes requires redefining the interface to all
visitors, which is potentially costly. If the object structure classes
change often, then it's probably better to define the operations in
those classes.
[...] and also additional implementations of Figures will come
I think that for this reason alone the visitor pattern is not appropriate for your scenario. Whenever you add a new class to the hierarchy, you'd have to change the visitor interface and all its implementations. The visitor is more appropriate when your hierarchy is stable and it allows you to add extra behaviors easily, just by creating new visitor implementations.
Take a look at the acyclic visitor for an alternative. But think hard about using these patterns, they can make the design more complex than it should be.
I think the question is a bit overly-broad. We should know a little bit more about your application architecture, features and requirements. I'd just add another point of view to nikpon's one.
Consider the last point:
the classes defining the object structure rarely change, but you often
want to define new operations over the structure. Changing the object
structure classes requires redefining the interface to all visitors,
which is potentially costly. If the object structure classes change
often, then it's probably better to define the operations in those
classes.
So the answer depends on what actually your figures data are and which operations they must implement.
I'll give you an example where visitor patterns could be better:
A figure is only a collection of data that represent the actual figure (es. Circle: radius and center . Square side and center)
You have to draw figures across different systems/architectures where you are using different GUI/Rendering libraries
In a case like this there are 2 main consequences:
A figure class probably never changes, or it's changes can be hidden behind an interface that can never change. (es. A circle will always be defined by a center and a radius.)
You can't have a single method for drawing this objects since it changes accordingly to the used graphic library. If you put the drawing logic inside drawSelected(), than for every different graphic library you are using, you need to modify drawSelected implementation on each class(or use a suitable pattern to allow that).
In a case like this visitors benefits could be:
You can reuse the Figure classes across different platforms and graphic library, without any change
You can condense the drawing operations on a per[platform|library] concrete visitor classes. (es. DrawObjectsOnWindowsVisitor and DrawObjectsOnAndroidVisitor). If you need to support a different platform/library, you can simply add a visitor leaving figure classes untouched.
Btw this may not be the case, and eventually other pattern can be used to achieve these goals.
I would like to separate the API I'm working on into two sections: 'bare-bones' and 'cushy'. The idea is that all method calls in the 'cushy' section could be expressed in terms of the ones in the 'bare-bones' section, that is, they would only serve as convenience methods for the quick-and-dirty. The reason I would like to do this is that very often when people are beginning to use an API for the first time, they are not interested in details and performance: they just want to get it working.
Anybody tried anything similar before? I'm particularly interested in naming conventions and organizing the code.
One way to provide a discrete separation of 'cushy' vs 'bare-bones' would be using separate interfaces that are implemented by the same class. When writing an API I like to keep it as simple as possible. If you need lots of parameters, consider using a fluent interface.
Yes, I've done something like this before, and I tend to pre-pend a word that indicates what the extra functionality is doing.
For example, a basic Vector class might only perform very basic vector operations (add, dot product), and a Vectors class might have a variety of static helper methods (cross products, projections, etc). Then, a FluentVector incorporates all those helper operations, while mutating the underlying Vector.
However, this isn't the decorator pattern - decorator produces different "decorated" results with the same interface. This is the facade pattern - different interface with the same underlying function.
Also, keep in mind that your extended API may have a variety of different ways of delivering the same function. Back to my Vector example, one might not want to mutate the underlying Vector with each chained-operation and instead introduce a new Vector - this might be an ImmutableFluentVector or some such. The API would be identical, except for the specification of side-effects. Just something to keep in mind.
Since you're asking for nice names, commonly used is simple or basic API and extended API. The simple API uses, as mentioned by Simon Nickerson, the extended API technically by providing an abstraction. See also Facade Pattern
Assuming Barebone provides basic functionality and Cushy provides additional functionality:
public class Skeleton
{
public virtual void Info()
{
}
}
public class Adorner:Skeleton
{
private Skeleton _skeleton;
public Adorner(Skeleton skeleton)
{
_skeleton = skeleton;
}
public override void Info()
{
//apply adorning work
}
}
Skeleton bareBones = new Skeleton();
Adorner cushy = new Adorner(bareBones);
Somebody at work suggested Foo and FooHelper. I like it.