我需要扩展一种广泛使用双重调度模式的算法。
该算法操纵一些不同的数据类(很多类),每个类都需要相同的扩展名。
我不想修改现有的数据类(用于限制序列化问题),也不想修改算法类(用于限制回归)。所以我设计了一个使用新类的解决方案。
我想使用类似下面的示例,但java拒绝识别我的类型。
import Main.Data1;
import Main.ExtendedData;
public class Main
{
static interface OperatorDispatcher
{
void dispatchDoSomething( OperatorDispatch operator );
}
static class Data1 implements OperatorDispatcher
{
@Override
public void dispatchDoSomething( OperatorDispatch operator )
{
operator.doSomething( this );
}
}
static class Data2 implements OperatorDispatcher
{
@Override
public void dispatchDoSomething( OperatorDispatch operator )
{
operator.doSomething( this );
}
}
static interface OperatorDispatch
{
void doSomething( Data1 data );
void doSomething( Data2 data );
}
static class MyOperator implements OperatorDispatch
{
public void doSomething( Data1 data1 )
{
System.out.println( "doSomething with Data1 : " + data1 );
}
public void doSomething( Data2 data2 )
{
System.out.println( "doSomething with Data2 : " + data2 );
}
}
static interface ExtendedOperatorDispatch
{
void doSomething( Data1 data, Object extension );
void doSomething( Data2 data, Object extension );
}
static class MyExtendedOperator implements ExtendedOperatorDispatch
{
public void doSomething( Data1 data1, Object extension )
{
System.out.println( "doSomething with Data1 : " + data1 + " and " + extension );
}
public void doSomething( Data2 data2, Object extension )
{
System.out.println( "doSomething with Data2 : " + data2 + " and " + extension );
}
}
static interface ExtendedOperatorDispatcher extends OperatorDispatcher
{
void dispatchDoSomething( ExtendedOperatorDispatch operator );
}
/*
* I don't want to specialize this class for each data type.
*/
static class ExtendedData< T > implements ExtendedOperatorDispatcher
{
T _data;
Object _extension;
public ExtendedData( T data, Object extension )
{
_data = data;
_extension = extension;
}
@Override
public void dispatchDoSomething( OperatorDispatch operator )
{
/*
* ERROR : The method doSomething(Main.Data1) in the type Main.OperatorDispatch is not applicable for the arguments (T)
*/
operator.doSomething( _data );
}
@Override
public void dispatchDoSomething( ExtendedOperatorDispatch operator )
{
/*
* ERROR : The method doSomething(Main.Data1, Object) in the type Main.ExtendedOperatorDispatch is not applicable for the arguments (T, Object)
*/
operator.doSomething( _data, _extension );
}
}
public static void main( String[] args )
{
MyOperator operator = new MyOperator();
Data1 data10 = new Data1();
data10.dispatchDoSomething( operator );
Data1 data11 = new Data1();
data11.dispatchDoSomething( operator );
Data2 data20 = new Data2();
data20.dispatchDoSomething( operator );
MyExtendedOperator extendedOperator = new MyExtendedOperator();
ExtendedData< Data1 > extendedData10 = new ExtendedData< Data1 >( data10, "EXTENSION" );
extendedData10.dispatchDoSomething( operator );
extendedData10.dispatchDoSomething( extendedOperator );
ExtendedData< Data2 > extendedData20 = new ExtendedData< Data2 >( data20, "EXTENSION" );
extendedData20.dispatchDoSomething( operator );
extendedData20.dispatchDoSomething( extendedOperator );
}
}
你知道如何解决它或者你想到另一个解决方案,随时回答。
感谢的
答案 0 :(得分:0)
这可以解决问题,但可能有一个更简单的解决方案。 对于调度,如果性能不是至关重要的话,可以使用反射。 请注意,必须只有一种兼容的方法才能工作。
class ExtendedData<T> implements ExtendedOperatorDispatcher {
T _data;
Object _extension;
private Class<? extends Object> _dataClass;
private Class<? extends Object> _extensionClass;
public ExtendedData(T data, Object extension) {
_data = data;
_extension = extension;
_dataClass = (_data == null ? Object.class : _data.getClass());
_extensionClass = (_extension == null ? Object.class : _extension
.getClass());
}
@Override
public void dispatchDoSomething(OperatorDispatch operator) {
try {
Method foundMethod = null;
for (Method method : operator.getClass().getMethods()) {
Class<?>[] params = method.getParameterTypes();
if ("doSomething".equals(method.getName())
&& params.length == 1)
if (params[0].isAssignableFrom(_dataClass)) {
if (foundMethod == null)
foundMethod = method;
else
throw new IllegalArgumentException(
"Multiple method can be called");
}
}
foundMethod.invoke(operator, _data);
} catch (SecurityException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
@Override
public void dispatchDoSomething(ExtendedOperatorDispatch operator) {
try {
Method foundMethod = null;
for (Method method : operator.getClass().getMethods()) {
Class<?>[] params = method.getParameterTypes();
if ("doSomething".equals(method.getName())
&& params.length == 2)
if (params[0].isAssignableFrom(_dataClass) && params[1].isAssignableFrom(_extensionClass)) {
if (foundMethod == null)
foundMethod = method;
else
throw new IllegalArgumentException(
"Multiple method can be called");
}
}
foundMethod.invoke(operator, _data, _extension);
} catch (SecurityException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}