At work, we are developing an PHP application that would be later re-programmed into Java. With some basic knowledge of Java, we are trying to design everything to be easily re-written, without any headaches. Interesting problem came out when we tried to implement composite pattern with huge number of methods in leafs.
What are we trying to achieve (not using interfaces, it's just a quick example):
class Composite {
...
}
class LeafOne {
public function Foo( );
public function Moo( );
}
class LeafTwo {
public function Bar( );
public function Baz( );
}
$c = new Composite( Array( new LeafOne( ), new LeafTwo( ) ) );
// will call method Foo in all classes in composite that contain this method
$c->Foo( );
// same with Bar
$c->Bar( );
It seems like pretty much classic Composite pattern, but problem is that we will have quite many leaf classes and each of them might have ~5 methods (of which few might be different than others). One of our solutions, which seems to be the best one so far and might actually work, is using __call magic method to call methods in leafs.
Unfortunately, we don't know if there is an equivalent of it in Java.
So the actual question is: Is there a better solution for this, using code that would be eventually easily re-coded into Java? Or do you recommend any other solution? Perhaps there's some different, better pattern I could use here.
In case there's something unclear, just ask and I'll edit this post.
Edit:
Actual problem is that not every leaf class contains, for example, method Baz. If we used simple foreach to call Baz in every class, it'd give use bunch of errors, as there are certain classes that don't contain this method. Classic solution would be to have every single method from every single leaf class implemented into Composite class, each with different implementation. But this would make our composite class huge and messy with amount of methods we use.
So usual solution would look like this (Composite class):
class Composite implements Fooable, Bazable {
...
public function Foo( ) {
foreach( $this->classes as $class ) {
$class->Foo( );
}
}
public function Baz( ) {
...
}
}
To prevent our code to become real mess, we were thinking about something like:
class Composite {
...
public function __call( ) {
// implementation
}
}
But we aren't really sure if it's a good solution and if there's something similar also in Java (as asked already before edit).
Within Java you could consider using the visitor pattern whereby you pass a visitor object to each node in the tree and the node makes a callback to the visitor class to determine which behaviour should be performed.
This avoids any casting or explicitly checking the type of each node.
/**
* Visitor capable of visiting each node within a document.
* The visitor contains a callback method for each node type
* within the document.
*/
public interface DocumentNodeVisitor {
void visitWord(Word word);
void visitImage(Image img);
}
/**
* Base interface for each node in a document.
*/
public interface DocumentNode {
void applyVisitor(DocumentVisitor v);
}
/**
* Conrete node implementation representing a word.
*/
public class Word implements DocumentNode {
private final String s;
public Word(String s) { this.s = s; }
public String getValue() { return this.s; }
public void applyVisitor(DocumentVisitor v) {
// Make appropriate callback to visitor.
v.visitWord(this);
}
}
/**
* Conrete node implementation representing an image.
*/
public class Image implements DocumentNode {
public void applyVisitor(DocumentVisitor v) {
// Make appropriate callback to visitor.
v.visitImage(this);
}
}
public class Paragraph implements DocumentNode {
private final List<DocumentNode> children;
public Paragraph() {
this.children = new LinkedList<DocumentNode>();
}
public void addChild(DocumentNode child) {
// Technically a Paragraph should not contain other Paragraphs but
// we allow it for this simple example.
this.children.add(child);
}
// Unlike leaf nodes a Paragraph doesn't callback to
// the visitor but rather passes the visitor to each
// child node.
public void applyVisitor(DocumentVisitor v) {
for (DocumentNode child : children) {
child.applyVisitor(v);
}
}
}
/**
* Concrete DocumentVisitor responsible for spell-checking.
*/
public class SpellChecker implements DocumentVisitor
public void visitImage(Image i) {
// Do nothing, as obviously we can't spellcheck an image.
}
public void visitWord(Word word) {
if (!dictionary.contains(word.getValue()) {
// TODO: Raise warning.
}
}
}
Visitor design pattern is a quite good solution. But you have to consider possible changes in the structure, e.g. new Leaf class will make you implement applyVisitor and add visit* method to every other Visitor you have created. So Visitor really helpts you to add behaviour to structured objects at price of that structure not changing too often. If the structure changes often and the algorithms not so much, you might consider having different composites for objects with same interfaces. If you want to do it the dirty way as you currently do in PHP, look at Java reflection API. Nice solution would be imho dynamic calls (as in Ruby or Python). You can simulate those, but that would be much work... So my answer is use the Visitor with care or consider different Composites for objects with different behaviour.
Related
I have gone through http://www.dofactory.com/net/design-patterns in trying to find out the most efficient to create a design pattern in which "one visible class utilizes many hidden classes" to create a fluent API. Below is the code I currently have:
public class VisibleClass {
Private OrderClass order;
private ReceiptClass receipt;
public VisibleClass makeOrder() {
if (!(order instanceof OrderClass))
order = new OrderClass();
order.make();
return this;
}
public VisibleClass printReceipt() {
if (!(receipt instanceof ReceiptClass))
receipt = new ReceiptClass();
receipt.print();
return this;
}
}
class OrderClass implements IOrder {
public void make() {}
}
class ReceiptClass implements IReceipt {
public void print() {}
}
interface IOrder { void make(); }
interface IReceipt { void print(); }
Here is how I am currently using the API:
public static void main(String[] args) {
VisibleClass x = new VisibleClass();
x.makeOrder().printReceipt();
}
It this a good approach? Can a better approach be used for it?
*EDIT: Also, I should add that the VisibleClass will implement all methods of the hidden classes.
Your approach is quite good. Here some recommendations:
1 Change class member types to their interfaces as for 'Program to an interface, not an implementation' principle:
public class VisibleClass {
private IOrder order;
private IReceipt receipt;
2 Do you really need to check class types in makeOrder and printReceipt methods ? Creating instances after null check seems enough:
public VisibleClass makeOrder() {
if (null == order)
order = new OrderClass();
order.make();
return this;
}
public VisibleClass printReceipt() {
if (null == receipt)
receipt = new ReceiptClass();
receipt.print();
return this;
}
3 This approach is valid until methods of VisibleClass will be called by a single thread. If you're going to place it in a multi-thread program, you should ensure that there are only one instances of OrderClass and ReceiptClass each. There are 3 ways you can follow:
a. Create instaces of OrderClass and ReceiptClass in constructor and make VisibleClass singleton.
b. Make OrderClass and ReceiptClass singleton and remove new lines.
c. Create instances surrounded with synchronized block in makeOrder and printReceipt methods.
one visible class utilizes many hidden classes
don't do that with business classes. Fluent syntax's is great for configuration etc, but not for plain business code.
The reason is that the class itself losses control over it's state which can put it in an inconsistent state (i.e generate faulty results).
There is even a principle called Law of Demeter which is about just that.
If you have a business requirement that a receipt should be printed on a new order you should just return it as a return value.
var receipt = visibleClass.makeOrder();
As for using interfaces for entity/business classes, why do you do that? why would you want to abstract away those? The usually do not have any other dependencies or different types of implementations.
You can try using the Facade Design pattern
Or may be try using a Decorator Pattern
I'm running into real trouble trying to complete a practical that requires using strategy and composite pattern. I am trying to create a collection of vehicles which can have different behavior depending on the surface they are on. However, these vehicles can have more than one behaviour on a surface - for example, they could have snow drive and rain drive at the same time, if the weather conditions are set to snow and rain.
I have a class called AbstractVehicle, which has two concrete subclasses, Car and Boat.
I then have an interface called IBehaviour. Implementing this interface is two abstract classes called LandBehaviour and WaterBehaviour (which are the top tier of the composite pattern). Each of these have a collection of subclasses. Focussing solely on LandBehaviour, its subclasses are SnowBehaviour, StandardBehaviour and a few others including LandAssembly.
The idea was that I would put the code for the upper-tier of composite in LandBehaviour. Then, each of the concrete subclasses would have empty implementations of the add, remove and list parts of composite, with the LandAssembly class containing the code needed to actually combine various behaviours together.
This is intended to produce the result that, for example, a car could have both StandardBehaviour and SnowBehaviour at the same time.
Rather than posting large amounts of code (and there is a lot of it), I was hoping for some feedback on the basic structure I am trying to implement. I am getting a few errors right now such as null pointer exceptions and rather than spent a long time trying to fix them, I wanted to get an idea on whether the layout of the project was right to begin with.
Edit: Adding code - which generates a null pointer exception
This is my AbstractVehicle class:
public AbstractVehicle (IBehaviour behaviourIn) {
behaviour = behaviourIn;
}
public void setBehaviour(IBehaviour ib) {
behaviour = ib;
}
public IBehaviour getBehaviour() {
return behaviour;
}
public void move() {
behaviour.ensureCorrectBehaviour();
}
The car subclass:
public Car () {
super(new StandardBehaviour());
}
The IBehaviour interface:
public interface IBehaviour {
public void ensureCorrectBehaviour();
}
The LandBehaviour abstract class:
public void ensureCorrectBehaviour() {
}
public ILandBehaviour () {
}
private ILandBehaviour landBehaviour;
public ILandBehaviour (ILandBehaviour landBehaviour) {
this.landBehaviour = landBehaviour;
}
public ILandBehaviour getBehaviour() {
return landBehaviour;
}
public abstract void addBehaviour(ILandBehaviour behaviour);
public abstract void removeBehaviour(ILandBehaviour behaviour);
public abstract ILandBehaviour[] getBehaviours();
An example of a concrete behaviour subclass (RacingBehaviour):
public RacingBehaviour(ILandBehaviour landBehaviour) {
super(landBehaviour);
}
public RacingBehaviour() {}
#Override
public void ensureCorrectBehaviour() {
System.out.println("Vehicle is racing.");
}
public void addBehaviour(ILandBehaviour behaviour) {}
public void removeBehaviour(ILandBehaviour behaviour) {}
public ILandBehaviour[] getBehaviours() {
return null;
}
And finally the LandAssembly class:
public class LandAssembly extends ILandBehaviour {
private List<ILandBehaviour> behaviours;
public LandAssembly(ILandBehaviour landBehaviour) {
super(landBehaviour);
behaviours = new ArrayList<ILandBehaviour>();
}
public LandAssembly() {}
public void addBehaviour(ILandBehaviour behaviour) {
behaviours.add(behaviour);
}
public void removeBehaviour(ILandBehaviour behaviour) {
behaviours.remove(behaviour);
}
public ILandBehaviour[] getBehaviours() {
return behaviours.toArray(new ILandBehaviour[behaviours.size()]);
}
}
I am using this runner:
AbstractVehicle aCar = new Car(120);
aCar.move();
ILandBehaviour snow = new SnowBehaviour();
ILandBehaviour racing = new RacingBehaviour();
ILandBehaviour as = new LandAssembly();
as.addBehaviour(snow);
as.addBehaviour(racing);
Before I implemented the composite, everything was fine. I was able to use the client to create a new car, call its move() method, then change its behaviour, call move() again and see the difference. I'm aware however that I'm now kinda leaving the ensureCorrectBehaviour() method in my implementation of the composite pattern, which is obviously wrong. I'm also aware that after doing this, the "new" part of the Car constructor didn't work - I had to add an empty constructor each behaviour.
I can see glaring problems in the code I've created, I just don't quite see how to fix them.
If you are concerned about the design patterns, a class diagram would be extremely useful. You have many features, and you group those features into higher levels of abstractions (such as snow/land/water/etc.) But your vehicle only takes in one behavior. Does a vehicle need to be able to have multiple features? (Surely it does as you mention).
You might consider having concretely-defined strategies in your class, where each implementation of the strategy can vary.
public abstract class Bird
{
protected BirdCallStrategy callStrat;
protected FlyStrategy flyStrat;
}
public class Duck
{
public Duck()
{
callStrat = new QuackStrategy();
flyStrategy = new FlySouthForWinterStrategy(TimeOfYear);
}
}
public class Chicken
{
public Chicken()
{
callStrat = new CluckStrategy();
flyStrat = new NoFlyStrategy();
}
}
This works well if you have distinct abstractions for your strategies. In this case Flying and BirdCalling have nothing to do with each other, but they are allowed to vary by implementation at runtime (Quacking, chirping or flying, not flying, etc.)
If however, you want to create varying instances on the fly without subtyping, you might want to look into the Decorator pattern. The decorator pattern allows you to apply any combination of "features" to an instance at run-time.
So you might end up with an object that is instantiated such as:
Window decoratedWindow = new HorizontalScrollBarDecorator (
new VerticalScrollBarDecorator(new SimpleWindow()));
My problem is as follows:
We have an Algorithm that works internally with
Expression-objects that have a "String getContent()" method
Manipulator-objects that manipulate on Expressions using the "Expression manipulate(Expression e)" method
This will become a framework in Java.
To solve a real problem, one needs to give a specific implementation
of both an Expression and a Manipulator and the Algorithm class will do the rest.
Let's say we need a ProblemExpression and a ProblemManipulator
for a specific problem.
The ProblemExpression may contain a lot of new fields,
which can be used by the ProblemManipulator.
Right now, I can only think of two ways to write clean code:
Let ProblemManipulator.manipulate assume its arguments are ProblemExpressions
Use instanceOf
But I've got the feeling this is not how I should do it.
Any other suggestions?
Regards and thank you in advance,
Xaero.
Sounds like you should use a Generic. Like
interface Manipulator<E extends Expression> {
public void manipulate(E expression);
}
class ProblemManipulator implements Manipulator<ProblemExpression> {
public void manipulate(ProblemExpression expression) {
// expression is a ProblemExpression
}
}
As "Problem" is a different problem, it can be an interface that extends Expression like so:
interface IProblemExpr extends Expression
{ //additional methods
}
class ProblemExpression implements IProbExpr
{
}
class ProblemManipulator()
{
ProblemManipulator(IProblemExpr expr)
{
..
}
}
Generics are not enough, if both ProblemExpresions and ProblemManipulators can be accessed publicly.
At first i thought some kind of factory framework would do the trick.
I.e., either Expressions need to be able to create Manipulators or vice-versa.
for example, say ProblemManipulators were private inner classes of ProblemExpressions - obtained from Expression#createManipulator(...).
However, this does not quite do the trick ... in the end, if the Algorithm is allowed to 'hold onto references to' both the Expression and Manipulator, and can obtain different unrelated implementations, then the Algorithm implementation can always (if incorrectly written) wind up invoking the wrong Manipulator for a given Expression - nothing can be done at compile time to prevent this runtime mistake as all Manipulators can be invoked with any Expression.
So, it seems to me that invocation of the Manipulator (or Expression) must 'go thru' the Expression (or conversely the Manipulator) thus ensuring that the correct Manipulator is invoked for the given Expression.
I.e., Expression needs 'manipulate()' method which delegates to the appropriate Manipulator.
I studied the way generics work, and I came up with the following solution:
First, I created a two classes, one for the expression and one for the manipulator:
public class ObjectExpression { }
public class ObjectManipulator <E extends ObjectExpression> {
public void calculate(Set<E> objects) {
... // Do something
}
}
Next, I created an Algorithm class, which is generic.
Two classes are needed:
Some expression
Something that manipulates this type of object
We get:
public class Algorithm <F extends ObjectExpression, E extends ObjectManipulator<F>> {
E om;
public Algorithm( E om ) {
this.om = om;
}
public void run(Set<F> objects) {
om.calculate(objects);
}
}
Then, I created an implementation for the String case:
we need an expression and a manipulator
public class StringExpression extends ObjectExpression {
}
public class StringManipulator extends ObjectManipulator<StringExpression> {
#Override
public void calculate(Set<StringExpression> objects) {
// Do String stuff
}
}
Then, we can run the Algorithm as follows for Objects:
Algorithm<ObjectExpression, ObjectManipulator<ObjectExpression>> algo1 = new Algorithm<ObjectExpression, ObjectManipulator<ObjectExpression>>(manipo);
Set<ObjectExpression> objects = new HashSet<ObjectExpression>();
... // fill set
algo1.run(objects);
And for Strings:
StringManipulator manips = new StringManipulator();
Algorithm<StringExpression, StringManipulator> algo2 = new Algorithm<StringExpression, StringManipulator>(manips);
Set<StringExpression> strings = new HashSet<StringExpression>();
... // fill set
algo2.run(strings);
To me, this seems an elegant solution.
What do you think?
Any alternatives/improvements?
I've run into a situation in which I was to extend the functionality of a given class, but I'm not sure of the best way to go about this. I started by invoking functionality "upwards" and have now switched to "downwards", but I see issues with both. Let me explain what I mean. First, the "upwards" approach:
public class ParentValidator
{
public void validate() {
// Some code
}
}
public class ChildValidator extends ParentValidator
{
#Override
public void validate() {
super.validate();
// Some code
}
}
public class GrandchildValidator extends ChildValidator
{
#Override
public void validate() {
super.validate();
// Some code
}
}
This functions perfectly well, but it requires that I always remember to place super.validate() in my method body or the logic in the parent class(es) won't be executed. In addition, extension in this manner can be considered "unsafe" due to the fact that a child class could actually replace/modify the code defined in the parent class. This is what I call invoking methods "upwards" because I'm invoking methods from higher level classes as I go.
To counter these shortfalls, I decided to make ParentValidator.validate() final and have it invoke a different method. Here's what my code was modified to:
public class ParentValidator
{
public final void validate() {
// Some code
subValidate();
}
protected void subValidate() {}
}
public class ChildValidator extends ParentValidator
{
#Override
public final void subValidate() {
// Some code
subSubValidate();
}
protected void subSubValidate() {}
}
public class GrandchildValidator extends ChildValidator
{
#Override
public void subSubBalidate() {
// Some code
subSubSubValidate();
}
protected void subSubSubValidate();
}
This is what I was referring to when I say that I'm calling downwards as each class invokes methods on classes "down" the inheritance chain.
Using this approach, I can be guaranteed that the logic in the parent class(es) will be executed, which I like. However, it doesn't scale well. The more layers of inheritance I have, the uglier it gets. At one level, I think this is very elegant. At two levels, it starts to look shoddy. At three or more, it's hideous.
In addition, just as I had to remember to invoke super.validate() as the first line of any of my children's validate methods, I now have to remember to invoke some "subValidate" method at the end of any of my parent's validate methods, so that didn't seem to get any better.
Is there a better way to do this type of extension that I haven't even touched on. Either of these approaches have some serious flaws and I'm wondering if there's a better design pattern I could be using.
In what you describe as your first approach you are using simple inheritance, your second approach is closer to what the Gang of Four [GoF] called a Template Method Pattern because your parent class is using the so-called Hollywood Principle: "don't call us, we'll call you".
However, you could benefit from declaring the subvalidate() method as abstract in the parent class, and by this, make sure all subclasses are forced to implement it. Then it would be a true template method.
public abstract class ParentValidator
{
public final void validate() {
//some code
subValidate();
}
protected abstract void subValidate() {}
}
Depending on what you are doing there are other patterns that could help you do this in a different manner. For instance, you could use a Strategy Pattern to peform the validations, and by this favoring composition over inheritance, as suggested before, but a consequence is that you will need more validation classes.
public abstract class ParentValidator
{
private final ValidatorStrategy validator;
protected ParentValidator(ValidatorStrategy validator){
this.validator = validator;
}
public final void validate() {
//some code
this.validator.validate();
}
}
Then you can provide specific validation strategies for every type of Validator that you have.
If you want to get the best of both worlds you might considering implementing the solution as a Decorator Pattern where subclasses can extend the functionality of a parent class and still stick to a common interface.
public abstract class ValidatorDecorator implements Validator
{
private final Validator validator;
protected ParentValidator(Validator validator){
this.validator = validator;
}
public final void validate() {
//some code
super.validate(); //still forced to invoke super
this.validator.validate();
}
}
All patterns have consequences and advantages and disadvantages that you must consider carefully.
I'd prefer to 1) program against interfaces, and 2) opt for composition over inheritance. This is how I have done. Some people like it, some do not. It works.
// java pseudocode below, you'll need to work the wrinkles out
/**
* Defines a rule or set of rules under which a instance of T
* is deemed valid or invalid
**/
public interface ValidationRule<T>
{
/**
* #return String describing invalidation condition, or null
* (indicating then that parameter t is valid */
**/
String apply(final T t);
}
/**
* Utility class for enforcing a logical conjunction
* of zero or more validatoin rules on an object.
**/
public final class ValidatorEvaluator
{
/**
* evaluates zero or more validation rules (as a logical
* 'AND') on an instance of type T.
**/
static <T> String apply(final T t, ValidationRule<T> ... rules)
{
for(final ValidationRules<T> v : rules)
{
String msg = v.apply(t);
if( msg != null )
{
return msg; // t is not valid
}
}
return null;
}
}
// arbitrary dummy class that we will test for
// i being a positive number greater than zero
public class MyFoo
{
int i;
public MyFoo(int n){ i = n; }
///
}
public class NonZeroValidatorRule implements ValidatorRule<MyFoo>
{
public String apply(final MyFoo foo)
{
return foo.i == 0 ? "foo.i is zero!" : null;
}
}
// test for being positive using NonZeroValidatorRule and an anonymous
// validator that tests for negatives
String msg = ValidatorEvaluator.apply( new MyFoo(1),
new NonZeroValidatorRule(),
new ValidatorRule<MyFoo>()
{
public String apply(final MyFoo foo)
{
return foo.i < 0 ? "foo.i is negative!" : null;
}
}
);
if( msg == null )
{
\\ yay!
...
}
else
{
\\ nay...
someLogThingie.log("error: myFoo now workie. reason=" + msg );
}
More complex, non-trivial evaluation rules can be implemented this way.
The key here is that you should not use inheritance unless there exists a is-a relationship. Do not use it just to recycle or encapsulate logic. If you still feel you need to use inheritance, then don't go overkill trying to make sure that every subclass executes the validation logic inherited from the superclass. Have implementations of each subclass do an explicit execution on super:
public class ParentValidator
{
public void validate() { // notice that I removed the final you originally had
// Some code
}
}
pubic class ChildValidator extends ParentValidator
{
#Override
public void validate() {
// Some code
super.validate(); // explicit call to inherited validate
// more validation code
}
}
Keep things simple, and don't try to make it impossible or fool-proof. There is a difference between coding defensively (a good practice) and coding against stupid (a futile effort.) Simply lay out coding rules on how to subclass your validators. That is, put the onus on the implementors. If they cannot follow the guidelines, no amount of defensive coding will protect your system against their stupidity. Ergo, keep things clear and simple.
I prefer to using composition over inheritance if your subSubSubValidate is related general functionality. You can extract new class and move it there than you can use it without inheritance in the other classes.
There is also
"Favor 'object composition' over
'class inheritance'." (Gang of Four
1995:20)
maybe a look at the visitor pattern may help you to develop your pattern.
Here are some information on it : http://en.wikipedia.org/wiki/Visitor_pattern
Alrite, I am gonna jump straight to the code:
public interface Visitor {
public void visitInventory();
public void visitMaxCount();
public void visitCountry();
public void visitSomethingElse();
public void complete();
//the idea of this visitor is that when a validator would visit it, it would validate data
//when a persister visits it, it would persist data, etc, etc.
// not sure if I making sense here...
}
public interface Visitable {
public void accept(Visitor visitor);
}
here is a base implementation:
public class StoreValidator implements Visitor {
private List <ValidationError> storeValidationErrors = new ArrayList<ValidationError>();
public void addError(ValidationError error) {
storeValidationErrors.add(error);
}
public List<ValidationError> getErrors() {
return storeValidationErrors;
}
public void visitInventory() {
// do nothing
}
public void visitMaxCount() {
//do nothing
}
//... etc.. all empty implementations
}
You will see why I did an empty implementation here... I would write a validator now.. which extends StoreValidator
public XYZValidator extends StoreValidator {
#Override
public void visitInventory(Visitable visitable) {
// do something with visitable .. cast it to expected type
// invoke a DAO, obtain results from DB
// if errors found, do addError(new ValidationError()); with msg.
}
#Override
public void visitMaxCount(Visitable visitable) {
//do something with visitable..
}
// I wouldn't implement the rest coz they wouldn't make sense
// in XYZValidator.. so they are defined as empty in StoreValidator.
}
Now here is what a visitable would look like:
public Store implements Visitable {
public void accept(Visitor visitor) {
visitor.visitInventory();
visitor.visitMaxCount();
}
}
I could have code that does something like this on a list of Store objects:
List<Store> stores; //assume this has a list of stores.
StoreValidator validator = new XYZValidator(); //or I would get it from a validatorfactory
for(Store store: stores) {
store.accept(validator); // so even if you send a wrong validator, you are good.
}
Similarly you would have ABCValidator which would provide implementation for other methods (visitCountry / visitSomethinElse) and it would extend from StoreValidator. I would have another type of Object (not Store) defining accept method.
I do see a problem here...
Say, I need a FileValidator which is different from StoreValidator, I would expect it to have none of these business related validations such as visitInventory(), etc. But, by having a single interface Visitor, I would endup declaring all kinds of methods in Visitor interface. Is that correct? Is this how you do it?
I don't know if I got the pattern wrong, or if I am making any sense.
Please share your thoughts.
Some time ago I wrote something similar for my master thesis. This code is slightly
type safe than yours:
interface Visitable<T extends Visitor> {
void acceptVisitor(T visitor);
}
interface Visitor {
/**
* Called before any other visiting method.
*/
void startVisit();
/**
* Called at the end of the visit.
*/
void endVisit();
}
example:
interface ConstantPoolVisitor extends Visitor {
void visitUTF8(int index, String utf8);
void visitClass(int index, int utf8Index);
// ==cut==
}
class ConstantPool implements Visitable<ConstantPoolVisitor> {
#Override
public void acceptVisitor(ConstantPoolVisitor visitor) {
visitor.startVisit();
for (ConstanPoolEntry entry : entries) {
entry.acceptVisitor(visitor);
}
visitor.endVisit();
}
so yes, I think that this definitely a good and flexible design if, and only if, your data changes slower than your behaviour. In my example the data is Java bytecode, that is fixed (defined by the JVM specification). When "behaviour dominates" (I want to dump, compile, transform, refactor, etc my bytecode) the Visitor pattern let you to change/add/remove behaviour without touching your data classes. Just add another implementation of Visitor.
For the sake of simplicity assume that I must add another visit method to my Visitor interface: I would end in breaking all my code.
As alternative I would consider the strategy pattern for this scenario. Strategy + decorator is a good design for validation.
There is a problem with your code as given. The interface you give has methods such as
public void visitInventory();
but you then implement it in XYZValidator as
public void visitInventory(Visitable visitable)
The visitor pattern is a way to implement multiple dispatch in languages that do not do that automatically (such as Java). One of the requirements is that you have a group of related classes (i.e. a set of subclasses with a single super class). You don't have that here, so the visitor pattern is not appropriate. The task you are trying to do, however, is fine, it is just not the Visitor pattern.
In Java, you should think of the Visitor pattern if you have code like
public void count(Item item) {
if (item instanceof SimpleItem) {
// do something
} else if (item instanceof ComplexItem {
// do something else
} else ...
}
particulary if the subclasses of Item are relatively fixed.
I'm using a visitor pattern in a different way.. I have a specific Visitor interface for a type of object and this interface declares only one method - for visiting that object.. like this:
public interface TreeNodeVisitor {
void visit(TreeNode node);
}
the object TreeNode can accept TreeNodeVisitors which means he just calls it's visit method for the node and/or it's children..
The concrete implementation of the visitor implements the visit method and says what the visitor will do.. for example ContryVisitor, InventoryVisitor, etc
This approach should avoid your probleam..
You probably don't want to map a pattern directly to a single interface that everything following that pattern implements. Patterns are NOT Interfaces, they are general plans for implementing a solution.
In your example you would create a StoreVisitor interface and a FileVisitor interface for the different business objects that wish to use the Visitor pattern in the appropriate circumstances.
It might be that different Visitor implementations share common activities - so you could have a superinterface that defines those common functions. You could then code Visitable interfaces to use either the specific Visitable interface or it's superclass as appropriate.
For example, the FileVisitor and SQLTableVisitor interfaces might be a subclass of a DataStoreVisitor interface. Then:
VisitableStore accepts a StoreVisitor,
VisitableFile accepts a Filevisitor, or
VisitableDataStore accepts a DataStoreVistor (which might be an implementation of either FileVisitor or SQLTableVisitor).
forgive the random examples, I hope this makes sense.