Alfergon February 2016

Hierarchy issue on Composite with Java

I'm trying to do use a Composite pattern on Java in order to do a report, and I'm clearly forgetting how hierarchy and method overload work.

Let's say I have the following models:

public class Product {

    public String get(){
        return "Product";
    }

}

public class BProduct extends Product {

    public String getB() {
        return "BBBBB";
    }

}

public class CProduct extends Product {

    public String getC() {
        return "CCCCC";
    }

}

And the following converters:

import java.util.List;

public class Converter {

    private List<Converter> converters;

    public Converter() {

    }

    public Converter(List<Converter> converters) {
        this.converters = converters;
    }

    public void execute(Product product) {
        for (Converter converter : converters) {
            converter.execute(product);
        }
    }

}

public class BConverter extends Converter {

    @Override
    public void execute(Product product) {
        innerExecute(product);
    }

    public void innerExecute(Product product) {
        System.out.println(product.get() + " done on B normal.");
    }

    public void innerExecute(BProduct b) {
        System.out.println(b.getB() + " done on B special.");
    }

}

public class CConverter extends Converter {

    @Override
    public void execute(Product product) {
        System.out.println(product.get() + " done on C normal.");
    }

    public void execute(CProduct c) {
        System.out.println(c.getC() + " done on C special.");
    }

}

Testing it with the following test:

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

public class ProductConverterTest {

    @Test
    public void test() {
        List<Converter> converters = new ArrayList<>();
        converters.add(new BConverter());
        converters.add(new CConverter());
        Converter converter        

Answers


Supahupe February 2016

Your execute-method in the sub-converters always call the innerExecute-method from the superior class. In your example, remove innerExecute(Product proeuct) from the subclasses.

You can furthermore try to overwrite the toString()-Methode in product instead of get-method. Then use an Interface for the execute-Method.


hahn February 2016

the reason for this behaviour is that #execute method is overloaded. the choice of which overloaded method to invoke is made at compile time. in order to make it work as you want you would have to use dynamic selection, which would lead to either instanceOf check or overwriting the methods or pass/retrieve class of a product and compare like:

public class Converter {

    private List<Converter> converters;

    public Converter() {

    }

    public Converter(List<Converter> converters) {
        this.converters = converters;
    }

    public void execute(Product product) {
        for (Converter converter : converters) {
            converter.execute(product);
        }
    }

}

public class BConverter extends Converter {

    @Override
    public void execute(Product product) {
        if (product.getClass() == BProduct.class) {
            innerExecute((BProduct)product);
        } else {
            innerExecute(product);
        }
    }

    public void innerExecute(Product product) {
        System.out.println(product.get() + " done on B normal.");
    }

    public void innerExecute(BProduct b) {
        System.out.println(b.getB() + " done on B special.");
    }

}

public class CConverter extends Converter {

    @Override
    public void execute(Product product) {
        if (product.getClass() == CProduct.class) {
            innerExecute((CProduct)product);
        } else {
            innerExecute(product);
        }
    }

    public void innerExecute(Product product) {
        System.out.println(product.get() + " done on C normal.");
    }

    public void innerExecute(CProduct b) {
        System.out.println(b.getC() + " done on C special.");
    }

}

Post Status

Asked in February 2016
Viewed 3,100 times
Voted 5
Answered 2 times

Search




Leave an answer