Error in defining a selfmade superclass with subclasses - java

I wrote an abstract superclass distribution as folows, it contains a constructor, and two methods.
public abstract class Distribution
{
public Distribution(){}
public abstract void setParameters(HashMap<String,?> hm);
public abstract int getSample();
}
Hereafter, I wrote 4 subclasses ( Poisson, Geometric, Deterministic and Binomial ). These subclasses all look the same and are like this;
public class Binomial extends Distribution
{
BinomialDistribution distribution;
public Binomial()
{
super();
}
#Override
public void setParameters(HashMap<String,?> hm)
{
try
{
int n = 0;
double p =0.0;
if (hm.containsKey("n"))
if (hm.containsKey("p"))
p = Double.parseDouble((String) hm.get("p"));
else
throw new Exception("Exception: No p-value found");
else
throw new Exception("Exception: No n-value found");
distribution = new BinomialDistribution(n,p);
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
#Override
public int getSample()
{
return distribution.sample();
}
}
In another class I want to use these classes. I want to give a HashMap to the Distribution.setparameters method, and let the program decide which subclass that fits the parameters given in that HashMap.
If I want to define A distribution the other class, this doesn't seem to work.
Distribution arrivalLength1distr = new Distribution();
Can somebody tell me what I do wrong and how my problem could be solved ?
Thanks !

Related

How to pass a classname as an argument java [duplicate]

In Java, how can you pass a type as a parameter (or declare as a variable)?
I don't want to pass an instance of the type but the type itself (eg. int, String, etc).
In C#, I can do this:
private void foo(Type t)
{
if (t == typeof(String)) { ... }
else if (t == typeof(int)) { ... }
}
private void bar()
{
foo(typeof(String));
}
Is there a way in Java without passing an instance of type t?
Or do I have to use my own int constants or enum?
Or is there a better way?
Edit: Here is the requirement for foo:
Based on type t, it generates a different short, xml string.
The code in the if/else will be very small (one or two lines) and will use some private class variables.
You could pass a Class<T> in.
private void foo(Class<?> cls) {
if (cls == String.class) { ... }
else if (cls == int.class) { ... }
}
private void bar() {
foo(String.class);
}
Update: the OOP way depends on the functional requirement. Best bet would be an interface defining foo() and two concrete implementations implementing foo() and then just call foo() on the implementation you've at hand. Another way may be a Map<Class<?>, Action> which you could call by actions.get(cls). This is easily to be combined with an interface and concrete implementations: actions.get(cls).foo().
I had a similar question, so I worked up a complete runnable answer below. What I needed to do is pass a class (C) to an object (O) of an unrelated class and have that object (O) emit new objects of class (C) back to me when I asked for them.
The example below shows how this is done. There is a MagicGun class that you load with any subtype of the Projectile class (Pebble, Bullet or NuclearMissle). The interesting is you load it with subtypes of Projectile, but not actual objects of that type. The MagicGun creates the actual object when it's time to shoot.
The Output
You've annoyed the target!
You've holed the target!
You've obliterated the target!
click
click
The Code
import java.util.ArrayList;
import java.util.List;
public class PassAClass {
public static void main(String[] args) {
MagicGun gun = new MagicGun();
gun.loadWith(Pebble.class);
gun.loadWith(Bullet.class);
gun.loadWith(NuclearMissle.class);
//gun.loadWith(Object.class); // Won't compile -- Object is not a Projectile
for(int i=0; i<5; i++){
try {
String effect = gun.shoot().effectOnTarget();
System.out.printf("You've %s the target!\n", effect);
} catch (GunIsEmptyException e) {
System.err.printf("click\n");
}
}
}
}
class MagicGun {
/**
* projectiles holds a list of classes that extend Projectile. Because of erasure, it
* can't hold be a List<? extends Projectile> so we need the SuppressWarning. However
* the only way to add to it is the "loadWith" method which makes it typesafe.
*/
private #SuppressWarnings("rawtypes") List<Class> projectiles = new ArrayList<Class>();
/**
* Load the MagicGun with a new Projectile class.
* #param projectileClass The class of the Projectile to create when it's time to shoot.
*/
public void loadWith(Class<? extends Projectile> projectileClass){
projectiles.add(projectileClass);
}
/**
* Shoot the MagicGun with the next Projectile. Projectiles are shot First In First Out.
* #return A newly created Projectile object.
* #throws GunIsEmptyException
*/
public Projectile shoot() throws GunIsEmptyException{
if (projectiles.isEmpty())
throw new GunIsEmptyException();
Projectile projectile = null;
// We know it must be a Projectile, so the SuppressWarnings is OK
#SuppressWarnings("unchecked") Class<? extends Projectile> projectileClass = projectiles.get(0);
projectiles.remove(0);
try{
// http://www.java2s.com/Code/Java/Language-Basics/ObjectReflectioncreatenewinstance.htm
projectile = projectileClass.newInstance();
} catch (InstantiationException e) {
System.err.println(e);
} catch (IllegalAccessException e) {
System.err.println(e);
}
return projectile;
}
}
abstract class Projectile {
public abstract String effectOnTarget();
}
class Pebble extends Projectile {
#Override public String effectOnTarget() {
return "annoyed";
}
}
class Bullet extends Projectile {
#Override public String effectOnTarget() {
return "holed";
}
}
class NuclearMissle extends Projectile {
#Override public String effectOnTarget() {
return "obliterated";
}
}
class GunIsEmptyException extends Exception {
private static final long serialVersionUID = 4574971294051632635L;
}
Oh, but that's ugly, non-object-oriented code. The moment you see "if/else" and "typeof", you should be thinking polymorphism. This is the wrong way to go. I think generics are your friend here.
How many types do you plan to deal with?
UPDATE:
If you're just talking about String and int, here's one way you might do it. Start with the interface XmlGenerator (enough with "foo"):
package generics;
public interface XmlGenerator<T>
{
String getXml(T value);
}
And the concrete implementation XmlGeneratorImpl:
package generics;
public class XmlGeneratorImpl<T> implements XmlGenerator<T>
{
private Class<T> valueType;
private static final int DEFAULT_CAPACITY = 1024;
public static void main(String [] args)
{
Integer x = 42;
String y = "foobar";
XmlGenerator<Integer> intXmlGenerator = new XmlGeneratorImpl<Integer>(Integer.class);
XmlGenerator<String> stringXmlGenerator = new XmlGeneratorImpl<String>(String.class);
System.out.println("integer: " + intXmlGenerator.getXml(x));
System.out.println("string : " + stringXmlGenerator.getXml(y));
}
public XmlGeneratorImpl(Class<T> clazz)
{
this.valueType = clazz;
}
public String getXml(T value)
{
StringBuilder builder = new StringBuilder(DEFAULT_CAPACITY);
appendTag(builder);
builder.append(value);
appendTag(builder, false);
return builder.toString();
}
private void appendTag(StringBuilder builder) { this.appendTag(builder, false); }
private void appendTag(StringBuilder builder, boolean isClosing)
{
String valueTypeName = valueType.getName();
builder.append("<").append(valueTypeName);
if (isClosing)
{
builder.append("/");
}
builder.append(">");
}
}
If I run this, I get the following result:
integer: <java.lang.Integer>42<java.lang.Integer>
string : <java.lang.String>foobar<java.lang.String>
I don't know if this is what you had in mind.
You should pass a Class...
private void foo(Class<?> t){
if(t == String.class){ ... }
else if(t == int.class){ ... }
}
private void bar()
{
foo(String.class);
}
If you want to pass the type, than the equivalent in Java would be
java.lang.Class
If you want to use a weakly typed method, then you would simply use
java.lang.Object
and the corresponding operator
instanceof
e.g.
private void foo(Object o) {
if(o instanceof String) {
}
}//foo
However, in Java there are primitive types, which are not classes (i.e. int from your example), so you need to be careful.
The real question is what you actually want to achieve here, otherwise it is difficult to answer:
Or is there a better way?
You can pass an instance of java.lang.Class that represents the type, i.e.
private void foo(Class cls)

Either Usage & Error Handling in Java

My goal is to use the Either class alongside my Human, Weapon, and Magazine classes.
These are the different Human declarations I want to test. (No weapon, no mag, and has all)
Human noWeapon = new Human(null);
Human noMag = new Human(new Weapon(null));
Human hasAll = new Human(new Weapon(new Magazine(2)));
Currently, I'm creating an Either in the following way:
Human noWeapon = new Human(null);
Either <String, Human> either2 = new Right <String, Human>(noWeapon);
Right <String, Human> either2_right = (Right<String, Human>) either2;
I'm struggling to understand the inner workings of the Either class and the ways for which I can use it for error handling. I want to be able to catch these errors when they occur so I can know when the error is happening
either2_right.getRight().getWeapon().getMag().getCount();
Currently, this is throwing a NullPointerException error for obvious reasons - but my goal is to instead catch the error and know when it occured.
My Either class is as follows:
abstract class Either<A, B> { }
class Left<A, B> extends Either<A, B> {
public A left_value;
public Left(A a)
{
left_value = a;
}
public A getLeft(){
return this.left_value;
}
public <B2> Either<A,B2> flatMap(final Function<B,Either<A,B2>> f){
return (Either<A,B2>)this;
}
public <B2> Either<A,B2> map(final Function<B,B2> f){
return (Either<A,B2>)this;
}
}
class Right<A, B> extends Either<A, B> {
public B right_value;
public Right(B b)
{
right_value = b;
}
public B getRight(){
return this.right_value;
}
public <B2> Either<A,B2> flatMap(final Function<B,Either<A,B2>> f){
return f.apply(right_value);
}
public <B2> Either<A,B2> map(final Function<B,B2> f){
return new Right(f.apply(right_value));
}
}
I'm using Either for my following 3 classes:
Human
class Human {
Weapon w;
public Human(Weapon w)
{
this.w = w;
}
public Weapon getWeapon()
{
return w;
}
}
Weapon:
class Weapon {
Magazine m;
public Weapon(Magazine m)
{
this.m = m;
}
public Magazine getMag()
{
return m;
}
}
Magazine:
class Magazine {
private int count;
public Magazine(int c)
{
count = c;
}
public int getCount()
{
return count;
}
}
Thank you for any help I'm able to get!
I'm struggling to understand the inner workings of the Either class and the ways for which I can use it for error handling.
Let us start with the second part of the question, how can I use Either for error handling?
Either can hold one of two values, for error handling you can declare a method to return an Either that will hold a valid computation result or an Exception. For example:
public Either<ArithmeticException, Double> divide (Double x, Double y) {
try {
return new Right<ArithmeticException, Double>(x/y);
} catch (ArithmeticException e) {
return new Left<ArithmeticException, Double>(e);
}
}
The caller will not get an ArithmeticException if he try to divide by zero, he will receive an Either holding the exception, in this example he will get a Left. The convention is to hold valid return results in a Right and the other results in a Left.
The implementation you provided doesn't make it easy for the caller to check if he got a Right or a Left or make it easy to process the result regardless of it is a Right or a 'Left a more complete implementation of Either here provides that convenience (for instance getOrThrow to get a Right value or throw an exception if the Either is not a Right).

Using instances of a class as reference

I need some help on my class design or better said a reference to a common design pattern for a problem.
I am working in the aircraft industry. So far my programming skills are VBA and basic JAVA applications.
As an engineer my task is to create CAD Models for fixating components in and on to aircraft kitchens. To ensure a high reusability and to reduce development time I want to create a program which can recommend previous solutions.
Basically each aircraft operator can select from a catalog which galleys/kitchens (Monument) it would like to have installed. Inside these Monuments are multiple compartments. Inside a compartment we can install multiple equipment’s/components.
I would like to write a program which can tell me "you have installed these components together before -> In this compartment -> in that aircraft for that customer"
I have modeled the compartment, the monuments, and the aircraft. Each class extends form the same class BaseHolder:
public abstract class BaseHolder <I> {
private final ArrayList <I> heldItems = new ArrayList<I>();
public boolean addItem(final I i){
Objects.requireNonNull(i, "cannot add NULL");
return heldItems.add(i);
}
public boolean removeItem(I i){
return heldItems.remove(i);
}
public boolean contains(I i){
return heldItems.contains(i);
}
public int itemCount(){
return heldItems.size();
}
public boolean isEmpty(){
return heldItems.isEmpty();
}
public void Clear() {
heldItems.clear();
}
protected List<I> getHeldItems(){
return heldItems;
}
public I getElement(int n){
return heldItems.get(n);
}
}
public class Aircraft extends BaseHolder<Monument> {
// code
}
public class Monument extends BaseHolder<Compartment> {
private String name;
public Monument (String name){
this.setName(name);
}
// code
#Override
public boolean addItem(final Compartment c) {
Objects.requireNonNull(c, "cannot add NULL");
if (contains (c) ){
throw new IllegalArgumentException("Compartment already added!");
};
for(Compartment ctmp : getHeldItems()){
if (ctmp.getName().equals(c.getName() ) ) {
throw new IllegalArgumentException("Compartment with an identical name already exits");
}
}
return getHeldItems().add(c);
}
public Compartment getCompartment(int n){
return getHeldItems().get(n);
}
public Compartment getCompartment(String name){
for(Compartment ctmp : getHeldItems()){
if (ctmp.getName().equals(name) ) {
return ctmp;
}
}
return null;
}
}
public class Compartment extends BaseHolder<IWeighable>{
private String name = "";
private double MAX_LOAD = 0.0;
public Compartment (String name ,final double max_load){
this.setName(name);
updateMaxLoad(max_load);
}
// code
protected double getTotalLoad(){
// code
}
/**
*
* #param load
* #throws InvalidParameterException if max load not >= than 0.0
*/
public void setMaxLoad(final double load){
if (load >= 0.0){
this.MAX_LOAD = load;
} else {
throw new InvalidParameterException("max load must be greater than 0.0");
}
}
public boolean isOverloaded(){
return (getTotalLoad() > MAX_LOAD ) ;
}
}
The problem I am having is that this design seems to have many flaws. Apart from it being rather tedious: getElement(n).getElement(n).getElement(n)
Adding elements to a compartment results in all aircrafts using the same compartment, having all the same equipment’s/components installed. As it is the same object in the DB. An instance of the compartment would be need. Cloning the DB Compartment before adding it to an aircraft is no option. I need to be able to change the allowable loads, a change it for all. To resolve this I thought of using some type of “wrapper” class as in:
public class MonumentManager {
public ArrayList <Monument> monuments = new ArrayList<>();
public ArrayList <LinkObect> links;
class LinkObect{
private Compartment c;
private IWeighable e;
LinkObect(Compartment c, IWeighable e){
this.c = c;
this.e = e;
}
}
public boolean addMonument(Monument m){
return monuments.add(m);
}
public void addElementToCompartment(IWeighable e, Compartment c){
boolean known = false; //to check if the passed compartment is known/handeld to/by the MonumentManager
for (Monument m : monuments){
if ( m.getCompartment(c.getName() ) != null ) known = true;
}
if (known){
links.add(new LinkObect(c, e));
} else {
throw new IllegalArgumentException("Compartment is not inside a managed Monument!");
}
}
public List<Compartment> whereUsed(IWeighable e){
// TODO
}
}
This class might solve the problem but it is feels odd. Can anybody point me in the right direction towards a common design pattern etc. I am reading a book from the local library on design patterns. But it seems to be slightly above me. (as is maybe my task).
Any suggestions / help etc would be highly appreciated.
I hope I'm understanding this correctly.
One thing is the Component you want to install that has certain characteristics and another thing is some representation of what you have installed.
The information of your installation does not need to be in your Component but in something else, let's call it Installation.
Your Installation has to know 2 things:
What kind of Component it is.
What other Installations it has inside.
The installation will look something like this.
public class Installation {
private Component type;
private List<Installation> content;
public Installation(Component type){
this.type = type;
this.content = new ArrayList<Component>();
}
//you can have methods for add, remove, etc...
}
Feel free to ask further clarifications.

Composite pattern and instanceof

let's imagine the following situation: I want to design a bidding application (like ebay) with the composite design pattern
I create an abstract superclass like "BidComponent" (which has getName()) and two subclasses "Article" and "Category".
Category has a List which can contain other BidComponents, Article does not implement a List but a getPrice() method.
If I want to iterate through this structure and I want to print out the Category-Article-Structure I need instanceof:
if(element instanceof Article){
Article article = (Article)element;
System.out.println(article.getName() + ":" + article.getPrice());
}else{
Category category = (Category)element;
System.out.println(category.getName());
}
This seems pretty wrong to me. Is there a better way to realise this (So without always checking the type via instanceof)? I ask this question because I read several times that using instanceof is bad design...
//Edit to mention my problem with Visitors:
Ok. But let's imagine I want to search the highest bid to all products. So I have
public class HighestBidVisitor implements BidComponentVisitor{
private double highestBid = 0d;
public HighestBidVisitor(Category category){
visitCategory(category);
}
#Override
public void visitCategory(Category category){
Iterator<BidComponent> elementsIterator = category.iterator();
while(elementsIterator.hasNext()){
BidComponent bidComponent = elementsIterator.next();
//Now I have again the problem: I have to check if a component in the Categorylist is an article or a category
if(bidComponent instanceof Article) visitArticle((Article)bidComponent);
else visitCategory((Category)bidComponent);
}
}
#Override
public void visitArticle(Article article){
if(article.getPrice() > highestBid) highestBid = article.getPrice();
}
}
But now I have the same problem again (See comment in visitCategory). Or am I doing this wrong?
You want to use the visitor pattern.
public interface BidComponentVisitor {
void visitArticle(Article article);
void visitCategory(Category category);
}
Then your BidComponent class would have a visit method:
public abstract void visitChildren(BidComponentVisitor visitor);
The Composite and Visitor patterns often work together.
Edit: The key to avoiding instanceof when using the vistor pattern is how you implement the visitChildren method. In Category you would implement it like this:
#Override
public void visitChildren(BidComponentVisitor visitor) {
vistor.visitCategory(this);
for (BidComponent child : children) {
child.visitChidren(visitor);
}
}
Since Article has no children, it's implementation is simpler:
#Override
public void visitChildren(BidComponentVisitor visitor) {
vistor.visitArticle(this);
}
They key is each concrete class in the composite pattern knows it's own type, so it can call the specific visitor method that has a parameter with it's specific type.
One variation is to have enter and exit methods in the visitor for any class with children:
public interface BidComponentVisitor {
void visitArticle(Article article);
void enterCategory(Category category);
void exitCategory(Category category);
}
With the above interface, Category.visitChildren() would look like this:
#Override
public void visitChildren(BidComponentVisitor visitor) {
vistor.enterCategory(this);
for (BidComponent child : children) {
child.visitChidren(visitor);
}
vistor.exitCategory(this);
}
To print the tree, you could do something like this:
public class PrintingVisitor implements BidComponentVisitor {
private int depth = 0;
private void printIndent() {
for (int i = 0; i < depth; i++) {
System.out.print(" ");
}
}
public void visitArticle(Article article) {
printIndent();
System.out.println(article.toString());
}
public void enterCategory(Category category);
printIndent();
System.out.println(category.toString());
depth++;
}
public void exitCategory(Category category) {
depth--;
}
}
The disadvantage of the visitor patter is your visitor class needs to either hardcode every possible subclass, or have a generic visitOther() method.
You are doing the visitor implementation wrong. The different Components handle their own dispatching of elements. They know what type they are so you don't need to do any instanceof checks.
public interface Visitor{
void visit(Article a);
void visit(Category c);
}
abstract class BidComponent{
...
abstract void accept(Visitor v);
}
public class Category{
....
public void accept(Visitor v){
v.visit(this); // visit Category
for(Article a : getArticles()){
v.visit(a); //visit each article
}
}
}
Then a visitor to find the highest bid
public class HigestBidVisitor implements Visitor{
private final double highest;
void visit(Category c){
//no-op don't care
//or we could track which Category we have visited last
//to keep track of highest bid per category etc
}
void visit(Article a){
highest= Math.max(highest, a.getPrice());
}
}
Then to search all:
HigestBidVisitor visitor = new HighestBidVisitor();
BidComponent root = ...
root.accept(visitor);
double highest = visitor.getHighestPrice();
I can't think of any clean solution right now. You might have to update your implementation to either store Article and Category instances separately.
With your current implementation where a List<BidComponent> needs to be traversed and each element needs to be processed based on it's type, this approach can be a bit better:
abstract class BidComponent {
public abstract String process();
}
class Category extends BidComponent {
#Override
public String process() {
return getName();
}
}
class Article extends BidComponent {
#Override
public String process() {
return getName() + " " + getPrice();
}
}
List<BidComponent> list = ..;
for (BidComponent c : list) {
System.out.println(c.process());
}
Another way to decouple the processing logic from the classes/objects is:
Map<Class<?>, Function<BidComponent, String>> processors = new HashMap<>();
processors.put(Category.class, Category::getName());
processors.put(Article.class, a -> a.getName() + " " + a.getPrice());
List<BidComponent> list = ..;
for (BidComponent c : list) {
System.out.println(processors.get(c.getClass()).apply(c));
}
Note that this uses Java 8 lambdas but the same can be implemented with Java 7 or lower by using your own interface (similar to Function) or the ones provided by Guava or Apache Commons.

Questions about the Visitor pattern (sample in Java)

I'm just trying to understand the main benefits of using the Visitor pattern.
Here's a sample Java implementation
///////////////////////////////////
// Interfaces
interface MamalVisitor {
void visit(Mammal mammal);
}
interface MammalVisitable {
public void accept(MamalVisitor visitor);
}
interface Mammal extends MammalVisitable {
public int getLegsNumber();
}
///////////////////////////////////
///////////////////////////////////
// Model
class Human implements Mammal {
#Override
public void accept(MamalVisitor visitor) { visitor.visit(this); }
#Override
public int getLegsNumber() { return 2; }
}
//PIRATE HAS A WOOD LEG
class Pirate extends Human {
#Override
public int getLegsNumber() { return 1; }
public int getWoodLegNumber() { return 1; }
}
class Dog implements Mammal {
#Override
public void accept(MamalVisitor visitor) { visitor.visit(this); }
#Override
public int getLegsNumber() { return 4; }
}
///////////////////////////////////
///////////////////////////////////
class LegCounterVisitor implements MamalVisitor {
private int legNumber = 0;
#Override
public void visit(Mammal mammal) { legNumber += mammal.getLegsNumber(); }
public int getLegNumber() { return legNumber; }
}
class WoodLegCounterVisitor implements MamalVisitor {
private int woodLegNumber = 0;
#Override
public void visit(Mammal mammal) {
// perhaps bad but i'm lazy
if ( mammal instanceof Pirate ) {
woodLegNumber += ((Pirate) mammal).getWoodLegNumber();
}
}
public int getWoodLegNumber() { return woodLegNumber; }
}
///////////////////////////////////
///////////////////////////////////
public class Main {
public static void main(String[] args) {
// Create a list with 9 mammal legs and 3 pirate woodlegs
List<Mammal> mammalList = Arrays.asList(
new Pirate(),
new Dog(),
new Human(),
new Pirate(),
new Pirate()
);
///////////////////////////////////
// The visitor method
LegCounterVisitor legCounterVisitor = new LegCounterVisitor();
WoodLegCounterVisitor woodLegCounterVisitor = new WoodLegCounterVisitor();
for ( Mammal mammal : mammalList ) {
mammal.accept(legCounterVisitor);
mammal.accept(woodLegCounterVisitor);
// why not also using:
// legCounterVisitor.visit(mammal);
// woodLegCounterVisitor.visit(mammal);
}
System.out.println("Number of legs:" + legCounterVisitor.getLegNumber());
System.out.println("Number of wood legs:" + woodLegCounterVisitor.getWoodLegNumber());
///////////////////////////////////
// The standart method
int legNumber = 0;
int woodLegNumber = 0;
for ( Mammal mammal : mammalList ) {
legNumber += mammal.getLegsNumber();
// perhaps bad but i'm lazy
if ( mammal instanceof Pirate ) {
woodLegNumber += ((Pirate) mammal).getWoodLegNumber();
}
}
System.out.println("Number of legs:" + legNumber);
System.out.println("Number of wood legs:" + woodLegNumber);
}
}
///////////////////////////////////
I just wonder what is the main advantage for this case to use such a pattern. We can also iterate over the collection and get almost the same thing, except we don't have to handle a new interface and add boilerplate code to the model...
With Apache Commons, or a functional language, the classic way seems to do some map/reduce operation (map to the leg numbers and reduce with addition) and it's quite easy...
I also wonder why we use
mammal.accept(legCounterVisitor);
mammal.accept(woodLegCounterVisitor);
and not
legCounterVisitor.visit(mammal);
woodLegCounterVisitor.visit(mammal);
The 2nd option seems to remove the accept(...) method on the model part.
In many samples i've found, it seems that they don't use a common interface for model objects. I added it because like that i just have to add one visit(Mammal) method, instead of implementing one for each Mammal.
Is it good to make all my objects implement Mammal? (i guess sometimes it's just not possible anyway). Is it still a Visitor pattern like that?
So my questions are:
- do you see any advantage in my exemple for using visitors?
- if not, can you provide some concrete usecases for visitors?
- are visitors useful in functional programming languages
The only exemple that i found relevant for this pattern is the case of a pretty printer, where you keep in the visitor's state the offset to use during the visit of different nodes (for displaying an XML tree for exemple)
The visitor pattern is just double dispatch.
I'm not sure I agree with your implementation of a visitor. I'd implement something like this:
interface MammalVisitor {
void visit(Pirate pirate);
void visit(Human human);
void visit(Dog dog);
}
// Basic visitor provides no-op behaviour for everything.
abstract class MammalAdapter implements MammalVisitor {
void visit(Pirate pirate) {};
void visit(Human human) {};
void visit(Dog dog) {};
}
And then the implementation would become cleaner:
// We only want to provide specific behaviour for pirates
class WoodLegCounterVisitor extends MammalAdaptor {
private int woodLegNumber = 0;
#Override
public void visit(Pirate pirate) {
woodLegNumber += pirate.getWoodLegNumber();
}
public int getWoodLegNumber() { return woodLegNumber; }
}
In answer to your actual question, the main advantage of using the visitor is avoiding the need to do the "instanceof" checks. It gives you the ability to separate out the logic for processing a hierarchy into a separate class. It also gives you the ability to add new behaviour without changing the original classes.
Visitor pattern is a fancy switch case / pattern matching system to facilitate graph traversal.
As typical functional languages offer pattern matching and efficient ways to traverse graphs, interest is much more limited.
Even in JAVA, with instanceof or using enum, a visitor is more of a fancy way to perform things than a generic solution as many algorithms will not fit well into it.
The purpose of the Visitor Pattern is to separate the object structure (in your case, Mammal) from the algorithm (in your case, the counter Leg counter algorithm).
The whole idea is that your object (mostly in java, JavaBeans) doesn't change its structure at all, and only a new virtual function is introduced to introduce a new algorithm.
Unlike Jeff Foster's implementation, One can use Generics to make code easier. This brings specificity to your visitor, e.g.:
public interface MammalVisitor<T extends Mammal> {
public void visit(T mammal);
}
public class LegCounterVisitor implements MamalVisitor<Human> {
private int legNumber = 0;
#Override
public void visit(Human mammal) { legNumber += mammal.getLegsNumber(); }
public int getLegNumber() { return legNumber; }
}
public class WoodLegCounterVisitor implements MamalVisitor<Pirate> {
private int legNumber = 0;
#Override
public void visit(Pirate mammal) {legNumber += mammal.getWoodLegNumber(); }
public int getLegNumber() { return legNumber; }
}

Categories

Resources