装饰模式与多种泛型 [英] Decorator Pattern with multiple generics

查看:102
本文介绍了装饰模式与多种泛型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在做一些代码重构。所以我用一个装饰器设计来取代现有的继承设计。但我正在努力与多种泛型(可能它根本不可能)。





我目前有上述设计。有 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

  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 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?

解决方案

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆