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.
Related
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.
Is it ok to use empty interfaces for object modeling?
E.g. the following interface extends other empty interfaces in order the characterize the object 'Ferry':
public interface Ferry extends Watercraft, StationBased, Scheduled, Oneway, Motorized {}
Watercraft, StationBased, etc., are all empty interfaces, too, so they kind of act as a marker. However, they are not used by the JVM or compiler. These classes are only used for modeling purposes.
Is this good practice? Should an interface not usually provide some kind of common functionality, and not merely mark a class?
Yes, you can use empty interfaces for object modeling, but... Object modeling without any use-case is IMO overstretching it.
You write code to execute concrete actions, you model it to leverage general abstractions in the domain, and yes you can over-abstract your code.
Adding an interface in code is a classification or typification, which is only necessary as long as there is a taker for it. Otherwise it is plain dead code.
My worst encounter which sometimes still haunts me in my nightmares was an abstraction over business services, which essentially replaced it with a single method taking a map as arguments and returning an object which either contained the result or an error state. Effectively modeling a method invocation, but this time without types. Having forced this down on all business methods was simply a nightmare to unravel later.
There is nothing wrong with doing it that way except that you may discover quite quickly that changing the structure or adding new forms will become unpleasant.
I would probably consider a much more flexible enum option.
enum CraftAttributes {
Watercraft,
StationBased,
Scheduled,
Oneway,
Motorized;
}
class Ferry {
Set<CraftAttributes> attributes = EnumSet.of(
CraftAttributes.Watercraft
//...
);
}
There are lots of sweet thing you can do with unions and intersections of Sets that make for powerful but lucid code.
So I'm working on creating a visualization for a data structure in Java. I already have the implementation of the data structure (Binary Search Tree) to start with, but I need to add some additional functionality to the included node class. As far as conventions and best practices are concerned, should I create a subclass of the node with this added functionality or should I just modify what I have and document it there?
My question is similar to what's asked here but that's a little over my head.
I know it probably doesn't matter much for what I'm doing, so I'm asking this more as a general thing.
Edit: I probably should have been more clear. My modifications don't actually change the original implementation other than to add a couple of extra fields (x and y coords plus a boolean to set whether that node is highlighted) and functions to access/modify those fields. Also the node class I'm working with is included in the BST implementation
From reading your answers it seems like there's arguments to be made for either case. I agree that creating a separate class or interface is probably the best thing to do in general. Creating another class seems like it could get tricky since you'd still need a way to extract the data out of the node. The BST implementation I'm using is generic and doesn't have any such functionality by itself in the Node class or the BST class to just return the data so at minimum I have to add that.
Thanks for the informative replies.
The question to answer is, is the 'base functionality' useful, even disirable, when you're not visualizing the data structure?
You might not even want to extend the class at all. Without more detail, it seems to me that you have a datastructure that works. You could create a NEW class that knows how to vizualise it.
That is, instead of a datastructure than knows how to visualize itself, you have a datastructure, and another class that knows how to visualize the datastructure. Heck - you may find that that evolves into another whole class hierarchy because you might need to visualize queues, stacks, etc. etc. NOTHING to do wiht your binary search tree.
Since you're asking in general, here's the short answer: it really depends on the situation.
First off, subclasses are assumed to have an "IS-A" relationship with their parent classes. If you can't say that your new subclass IS A specific kind of the original class, you're asking the wrong question, and should be making a new, unrelated class.
If the new code is closely related to the core purpose of the class, and applies to all members of the class (e.g. all BSTs), it may be better to modify. High cohesion is good.
If your new code is related to the core purpose of the class but has to do with only some objects of that type (e.g. only BSTs that are balanced), subclassing is probably the way to go.
Depending on what you're changing, how many places your code is used, how many different people/organizations are using it, &c., your changes might lead to unexpected behavior in other code, so you should think twice before modifying existing code. That doesn't mean automatically subclassing commonly used things; that would often be wrong for the reasons described above.
In your specific case, I agree with n8wrl; since visualization has nothing to do with data structures, it's probably better to implement a whole separate Visualizable interface than make a DrawableBSTNode subclass.
I would say that in the general case of adding functionality to an existing implementation, you should extend the existing implementation rather than modify it.
And here's my reasoning. If that node is used anywhere aside from the Binary Search Tree implementation, then when you modify it you'll need to find everywhere it is used to ensure that none of those places conflict with your modifications. While just adding functionality in the form of new methods generally won't cause problems, it could cause problems. You never know how an object is used.
Second, even if it is only used in the Binary Search Tree, you'll still need to make sure that the BST's implementation will play nice with your modifications.
Finally, if you do extend it, you don't have to worry about points one and two. And you get the added bonus of having your modifications kept separate from the original implementation for all time. This will make it easier to track what you have done and comment on it.
There's no simple answer, knowing when and how to add functionality is a something you have to learn over time.
Just adding to the base class seems like the easy solution, but it's polluting your base class. If this is a class you could reasonably expect another program (or even part of your program) to use does the functionality you are adding make sense in the context of your class's responsibility? If it doesn't this is probably a bad move. Are you adding dependencies linking your base class to your specific use? Because if you are that's throwing code reuse right out the window.
Inheriting is the solution a lot of engineers gravitate to, and it's a seductive route. But as I've grown as an engineer it's one that I use sparingly. Inheritance should only be used in true is-a relationships, and you need to respect behavioral subtyping
or you are going to regret it later on. And since Java only allows single inheritance it means you only get one shot at subtyping.
Composition (especially with interfaces) is often a better idea. Often what looks like a is-a relationship is really a has-a one. Or sometimes all you really need is a helper class, that has many functions that take your original class as an argument.
However with composition there is one issue, want to store these objects in your tree. The solution here is interfaces. You don't want a tree that stores Nodes. You want to objects that have an interface that can give you a node.
public interface HasNode {
public Node getNode();
}
Your node class is a HasNode with getNode just returning this. Your NodeVisualizer class is also a HasNode, and now you can store NodeVisualizers in your tree as well. Of course now you have another problem, your tree could contain NodeVisualizers and Nodes, and that wouldn't be good. Plus when you get a HasNode back from the tree functions you have to cast them to the right instance and that's ugly. You'll want to use templates for that, but that's another answer.
Mixing up logically independent functionalities will cause a mess. Subclassing is a very special relationship, often overused. Subclassing is for Is-a-Kind relationships.
If you want to visualize something, why not create a fully independent Class for that? You could simply pass your Node object to this. (Or even better, use an Interface.)
I'm rather new to Java. After just reading some info on path finding, I read about using an empty class as an "interface", for an unknown object type.
I'm developing a game in Java based on hospital theme. So far, the user can build a reception desk and a GP's office. They are two different types of object, one is a Building and one is a ReceptionDesk. (In my class structure.)
My class structure is this:
GridObject-->Building
GridObject-->Item-->usableItem-->ReceptionDesk.
The problem comes when the usable item can be rotated and the building cannot. The mouse click event is on the grid, so calls the same method. The GP's office is a Building and the reception desk is a ReceptionDesk. Only the ReceptionDesk has the method rotate. When right clicking on the grid, if in building mode, I have to use this "if" statement:
if (currentBuilding.getClass.equals(ReceptionDesk.getClass)
I then have to create a new ReceptionDesk, use the rotate method, and the put that
reception desk back into the currentBuilding GridObject.
I'm not sure if I'm explaining myself very well with this question. Sorry. I am still quite new to Java. I will try to answer any questions and I can post more code snippits if need be. I didn't know that there might be a way around the issue of not knowing the class of the object, however I may also be going about it the wrong way.
I hadn't planned on looking into this until I saw how fast and helpful the replies on this site were! :)
Thanks in advance.
Rel
You don't want to check the class of an object before doing something with it in your case. You should be using polymorphism. You want to have the Interface define some methods. Each class implement those methods. Refer to the object by its interface, and have the individual implementations of those objects return their values to the caller.
If you describe a few more of the objects you think you need, people here will have opinions on how you should lay them out. But from what you've provided, you may want a "Building" interface that defines some general methods. You may also want a "UsableItem" interface or something more generic. Hospital could be a class that implements building. ReceptionDesk could implement UsableItem. Building could have a grid of UsableItem inside it.
If rotate() was a common method to all furniture that actually did some work, you may consider making an AbstractUsableItem class that was an abstract class implementing UsableItemand providing the rotate() method. If rotate was different in each implementing class, you would have that method in the interface, but each class, like ReceptionDesk would do its own thing with the rotate() method. Your code would do something like:
UsableItem desk = new ReceptionDesk();
desk.rotate()
In your example, if your mouse click on a screen rotated the object under it, and you really did need to check to see if the object could be rotated before doing something like that, you'd do
if (clickedObject instanceOf UsableItem) {
((UsableItem) clickedObject).rotate();
}
where UsableItem was the interface or abstract class. Some people feel that all design should be done via an interface contract and suggest an interface for every type of class, but I don't know if you have to go that far.
You might consider moving in a totally different direction and having the objects themselves decide what kind of action to take. For example, the GridObject interface might specify function declarations for handleRightClick(), handleLeftClick(), etc. What you'd be saying in that case is "any class who calls themselves a GridObject needs to specify what happens when they are right-clicked".
So, within the Building class, you might implement handleRightClick to do nothing (or to return an error). Within the ReceptionDesk class, you would implement handleRightClick to rotate the desk.
Your code snippet would then become:
currentBuilding.handleRightClick(... any necessary parameters ...);
You are correct to be worried. A good rule of thumb for Object-oriented design is that whenever you use a construct like if(x instanceof Y) or if(x.getClass().equals(Y.class)), you should start thinking about moving methods up or down, or extracting new methods.
Elliot and John have both presented good ideas on very different directions you could go, but they're both right in that you should definitely move in some direction. Object oriented design is there to help your code become more legible by making branching for different sorts of behaviors more implicit. Examining what sort of object you're looking at and determining what to do based on that can defeat the purpose of using object-oriented design.
I should also warn you that an interface isn't exactly an empty class. There are some significant differences between empty, abstract classes with abstract methods and interfaces. Instead of thinking of an interface as an empty class, think of an interface as a contract. By implementing an interface, your class promises to provide each of the methods listed in the interface.
I have several different classes coming from external sources (unmodifiable) that represent the same concept. For example Address. I have com.namespace1.Address (with fields houseNum, street, city), com.namespace2.Address (with fields h, s, c), namespace3.com.CoolAddress (with fields house_num, street, city).
The problem is that certain web services I use require certain Address object types so I am required to create a com.namespace1.Address given a namespace3.com.CoolAddress. The fields are easy enough to map but I'm looking for a pattern on how to do it.
From my point of view, an instance object AddressConverter doesn't make sense as there is no state (only behaviour) and when classes only have behaviour it boils down to static methods in a utility class. In the long term, anytime I need to map new objects to one another, I have one place to add/modify/remove methods. How it's done might change, but I know where the code sits (in once place) and can change the mapping when I need to.
Thoughts?
I think what you're looking for is a factory class. The factory pattern is used when you need to be able to instantiate one of several related classes, to be determined by the factory, not the developer.
See http://en.wikipedia.org/wiki/Factory_method_pattern
You're right to try to keep all this business logic in one place instead of doing ClassOne.toClassTwo(), ClassOne.toClassThree(),...
The most flexible way I can think of implementing this (but not the easiest by far) would be to have the factory start with a simple class with only basic common methods in it, and add handlers to a Hashtable or other container. That way you don't need concrete implementations of every possible combinations of features.
Of course it would be quicker to have a concrete implementation for each possible address variant, but there would be a fair amount of duplicated code, and it would be a little harder to add new address class types.
Since you can't modify the classes themselves, I'd suggest an implementation of the Adapter pattern for each direction. As you said, the adapter methods themselves can be static, but you can group both directions inside a single class so that the logic is all in one place.
At the end of the day you're going to be performing the same task no matter what you call it, or where you put the code. I'd suggest that both directions live in the same file, as they'll often both need updating when either direction changes.
If you are always converting to the same Class I would keep it simple and put all you conversion code in that Class and not worry about factories and the like, especially if you are only dealing with a couple of different classes. Why does there always have to be a complicated pattern for these things?!
public class A {
...
public static A convertB(B b) {
...
}
}
Are the classes you need to output final? If not, you could subclass them to create proper Adapters. Otherwise I'd go with dj_segfault's suggestion of a Factory with a table of handlers.
Or, wait -- is it just a web service you need to talk to? If so, there should be no reason your implementations of its datatypes can't be Adapters wrapping the input datatypes, or some intermediate object of your own.