1

I am trying to implement decorator pattern, my problem is I have different generated sources which will be passed to decorated masker, I do not have common parent which exposes the methods I need for doing the various masking in each masker so to solve this issue I thought about passing the type to the masker, and each masker will know the setter/getter he will be using, now what I want to do is pass the objects which have a common parent (without methods) and cast these objects using the passed type, now my problem is calling the getter, for example for NumbrMasker I know the getter/setter will be getNumber/setNumber but I am not sure how to call the methods for the passed type.

class NumberDecoratedMasker extends Masker {

private Class classType;

public DecoratedMasker (Masker masker, Class classType) {      
       this.classType = classType;
}

//for Number masker
public void mask(ParentModel parent) {
   //cast parent using classtype
   //call getNumber/setNumber for masking number

   if(masker != null)
      makser.mask(parent); // this is the decorated call for the other masker in the decorator structure
}
}


class ParentModel {
 //has nothing
}

class Elementa extends ParentModel {
  //has setters and getters for number
}

Now I initialize the Decorated with the classType of the object I want to mask

 Masker masker = new NumberDecoratedMakser(new SecondNumberDecoratedMasker(ElementA.class), ElementA.class);

ParentModel model = new ElementA();
masker.mask(moel);

I know reflection will be a solution in this case but I cannot go with it, is there a way to do this with java8?

1 Answer 1

3
public void mask(ParentModel parent, Supplier<ParentModel> getter,
                                     Consumer<ParentModel> setter) {
    setter.accept(parent);
    parent = getter.get();
}

Using a Class would have needed something ugly like:

interface Xetter<T> {
    void set(T x);
    T get();
}

public void mask(ParentModel parent, Class<Xetter<ParentModel>> xetter) {
}

Better would be to use the ...Property classes used in JavaFX, for instance StringProperty. This wraps a value type/class and provides the abstraction you seem to be looking for. Look at WritableValue.

As a last remark. In general one should use classes parametrized like:

public <T> T f(Class<T> type, Object value) {
    return type.cast(value);
}

After feedback: Still not quite sure about the decoration fitting the intended behaviour.

class Value {
}

class NumberValue extends Value {
    private Number number;
    void setNumber(Number number) {
        this.number = number;
    }
    Number getNumber() {
        return number:
    }
}

class Masker {
    public void mask(Value value) {
    }
}   

Either

class NumberDecoratedMasker<T extends NumberValue> extends Masker {
    private final Masker masker;
    private final Class<T> type;

    public NumberDecoratedMasker(Masker masker, Class<T> type) {
        this.masker = masker;
        this.type = type;
    }

    //for Number masker
    public void mask(Value value) {
        //cast parent using classtype
        //call getNumber/setNumber for masking number
        NumberValue n = type.cast(value);
        n.setNumber(42 + n.getNumber);
        value = n;
        if (masker != null) {
            masker.mask(value);
        }
    }
}
Masker masker = new NumberDecoratedMasker(
    new SecondNumberDecoratedMasker<NumberValue>(NumberValue.class), NumberValue.class);

or

class NumberDecoratedMasker extends Masker {
    private final Masker masker;
    private final Class<NumberValue> type;

    public NumberDecoratedMasker(Masker masker, Class<NumberValue> type) {
        this.masker = masker;
        this.type = type;
    }

    //for Number masker
    public void mask(Value value) {
        //cast parent using classtype
        //call getNumber/setNumber for masking number
        NumberValue n = type.cast(value);
        n.setNumber(42 + n.getNumber);
        value = n;
        if (masker != null) {
            masker.mask(value);
        }
    }
}
Masker masker = new NumberDecoratedMasker(
    new SecondNumberDecoratedMasker(NumberValue.class), NumberValue.class);

Value model = new NumberValue();
masker.mask(model);
Sign up to request clarification or add additional context in comments.

7 Comments

thanks for your answer, for you first suggestion does this mean i need to send a lambda with setter/getter to the method? I cannot understand your second proposed solution, can you provide more details, . also as I mentioned this is intended to be decorated method , which means I have a a reference to other masker which will also call mask inside my method, I edited the question to be more clear
It is good that you elaborated a bit more in your question. Still it is not entirely clear to me how ParentModel and Class are related, what they stand for and how they are used together. Hence my vague answer. You might give a fuller example, how the decorated uses both parameters, and what your decorator could do.
I added a more details example of my scenario, hope this is more clear
inside the masker I should not know about NumberValue, I know the comming type can have setNumber/getNumber method but I do not know about the type itself, so there could be another child for the parentModel which also has different setters that we know about so we create other decoratedmasker that can call these methods
Then one needs an interface (as my Xetter) in order to provide setNumber and getNumber. I suggest you try to develop first a prototype, before the code becomes too over-engineered.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.