装饰模式与多种泛型 [英] Decorator Pattern with multiple generics
问题描述
我目前正在做一些代码重构。所以我用一个装饰器
设计来取代现有的继承
设计。但我正在努力与多种泛型(可能它根本不可能)。
我目前有上述设计。有 IConstraint
检查
是一个针对实施约束的类。这些约束的具体实现是 SimpleConstraintA
和 SimpleConstraintB
它们都检查 ClassA的
。 Decorator
增强了约束,例如有一些限制,当指定的值不在范围内时不应检查。 ClassA
实现了接口 IA
和 IB
,这样 DecoratorA
和 DecoratorB
可以使用它。
设计的用法如下:
测试classToCheck = new Test(test);
IConstraint< Test>约束= new DecoratorA<>(new DecoratorB<>(new SimpleConstraint()));
布尔值= constraint.check(classToCheck);
所以我想要的是使用具有不同数量的输入参数和不同类型的代码。像:
Test classToCheckA = new Test(testA);
Test classToCheckB = new Test(testB);
IConstraint< Test>约束= new DecoratorA<>(new DecoratorB<>(new SimpleConstraint()));
布尔值= constraint.check(classToCheckA,classToCheckB);
或者:
Test classToCheckA = new Test(testA);
// TestB确实实现了与Test
相同的接口TestB classToCheckB = new TestB(testB);
IConstraint< Test>约束= new DecoratorA<>(new DecoratorB<>(new SimpleConstraint()));
布尔值= constraint.check(classToCheckA,classToCheckB);
或者:
Test classToCheckA = new Test(testA);
// TestB确实实现了与Test
相同的接口TestB classToCheckB = new TestB(testB);
// TestC确实实现了与Test
相同的接口TestC classToCheckC = new TestC(testC);
IConstraint< Test>约束= new DecoratorA<>(new DecoratorB<>(new SimpleConstraint()));
布尔值= constraint.check(classToCheckA,classToCheckB,classToCheckC);
我尝试使用 varargs
,列表
或 Object []
而不是 T
来自 check(obj:T)
但是我总是需要强制转换和很多异常处理(例如输入参数的数量需要正确),所以我并不满意。
以下代码是我尝试过的一个例子。就像你在 SimpleConstraint
检查
方法中看到的那样,只有类型( Test $ c>
public interface IConstraint< T extends ICheckable> {
public boolean check(T [] checkable);
}
公共类SimpleConstraint实现IConstraint< Test> {
@Override
public boolean check(Test [] checkable){
return true;
$ / code $ / pre
以上代码是不可能的: p>
Test classToCheckA = new Test(testA);
// TestB确实实现了与Test
相同的接口TestB classToCheckB = new TestB(testB);
IConstraint< Test>约束= new DecoratorA<>(new DecoratorB<>(new SimpleConstraint()));
布尔值= constraint.check(classToCheckA,classToCheckB);
设计是否有一些改进,以便支持不同数量的输入参数和不同的类型?
解决方案在上面的代码中,问题是,Test和TestB没有共同的祖先...
IConstraint< Test>约束= ...
布尔值=约束.check(classToCheckA,classToCheckB);
如果 TestB extends Test
或其他方式。
更好的方法是使用
IConstraint< ICheckable>约束=
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 check
s 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?
解决方案 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 =
这篇关于装饰模式与多种泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!