Decorator Pattern with multiple generics

时光总嘲笑我的痴心妄想 提交于 2019-12-08 10:28:12

问题


I am currently doing some code refactoring. So I came up replacing an existing inheritance design by a decorator design. But I am struggling with multiple generics (maybe it is simply not possible).

I have the above design at the moment. There is the IConstraint which checks a class against an implemented constraint. The concrete realization of those constraints are SimpleConstraintA and SimpleConstraintB both of them are checking some values from ClassA. The Decorator enhances the constraints e.g. there are some constraints which should not be checked when a specified value is not in range. ClassA implements the interfaces IA and IB so thatDecoratorA and DecoratorB can work with it.

The usage of the design is as followed:

Test classToCheck = new Test("test");
IConstraint<Test> constraint = new DecoratorA<>(new DecoratorB<>(new SimpleConstraint()));
boolean value = constraint.check(classToCheck);

So what I want is to use the code with a different number of input parameters and different types. Like:

Test classToCheckA = new Test("testA");
Test classToCheckB = new Test("testB");

IConstraint<Test> constraint = new DecoratorA<>(new DecoratorB<>(new SimpleConstraint()));
boolean value = constraint.check(classToCheckA, classToCheckB);

Or:

Test classToCheckA = new Test("testA");
// TestB does implement the same interfaces as Test
TestB classToCheckB = new TestB("testB");

IConstraint<Test> constraint = new DecoratorA<>(new DecoratorB<>(new SimpleConstraint()));
boolean value = constraint.check(classToCheckA, classToCheckB);

Or:

Test classToCheckA = new Test("testA");
// TestB does implement the same interfaces as Test
TestB classToCheckB = new TestB("testB");
// TestC does implement the same interfaces as Test
TestC classToCheckC = new TestC("testC");

IConstraint<Test> constraint = new DecoratorA<>(new DecoratorB<>(new SimpleConstraint()));
boolean value = constraint.check(classToCheckA, classToCheckB, classToCheckC);

I tried using varargs, Lists or Object[] instead of the T from the check(obj:T) but then I always need casts and a lot of exception handling (e.g. the number of input parameter need to be correct), so I was not satisfied.

The following code is one example what I tried. Like you see in the SimpleConstraint the check method only the type (Test) is allowed.

public interface IConstraint<T extends ICheckable> {
    public boolean check(T[] checkable);
}

public class SimpleConstraint implements IConstraint<Test> {
    @Override
    public boolean check(Test[] checkable) {
        return true;
    }
}

This is not possible with the above code:

Test classToCheckA = new Test("testA");
// TestB does implement the same interfaces as Test
TestB classToCheckB = new TestB("testB");
IConstraint<Test> constraint = new DecoratorA<>(new DecoratorB<>(new SimpleConstraint()));
boolean value = constraint.check(classToCheckA, classToCheckB);

Is there some improvement of the design so that different number of input parameters and different types can be supported?


回答1:


In the code above, the problem is, that Test and TestB does not have common ancestor...

IConstraint<Test> constraint = ...
boolean value = constraint.check(classToCheckA, classToCheckB);

You can make that work if TestB extends Test or other way around.

Better approach would be to have

IConstraint<ICheckable> constraint =


来源:https://stackoverflow.com/questions/37804192/decorator-pattern-with-multiple-generics

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!