我有几个Field
实体,Controller
以这种方式与它们相关联:(Field,Generic_Controller <--> Specific_Controller)
.我想在 Java 中实现每个Specific_Controller
与相应Field
和Generic_Controller
的关联。我怎样才能做到这一点?编译时更好。
编辑:这是一个任务的伪代码(也许会更清楚):
given X:Class and C:ServiceFor[X]
where C:ServiceFor[X] means:
C has method M with args(x:X) returning Any
goal:
get C:ServiceFor[X]
where C and X are given. // X is Field class or instance
that:
if there exits explicitly defined (C1 as ServiceFor[X]) and (C1 is child of C)
return C1 // ==Specific_Controller
otherwise:
return C // ==Generic_Controller
目前,我有实现,但它不是 DRY:我应该将控制器类与这是可能的方法之一,可能会导致问题(如果好奇,请参阅问题的第一个版本)。getController
主体保持同步。
import javax.swing.*;
interface Field
{
Object getValue();
/** Obtain name of field for internal usage
*/
String getName();
void setValue<T>(T value) throws InvalidValueException;
boolean isValid<T>(T value);
Controller getController(Class<?> genericController);
}
interface Controller {}
interface UIController extends Controller {
/** Return GUI widget responsible to manipulating value inside FormField
* instance
* (Control logic uses setValue() ) */
JComponent getInputControl();
}
interface UrlEncoder extends Controller {
/** Obtain value encoded for transmition through Web.
*
* some fields used privately in code are cut out inside this method
*/
String getURLEncodedValue();
}
class CommonUIController implements UIController { ... }
//-- MyField with specific implementations of controllers
class MyField
implements Field, UIController, UrlEncoder
{
// here methods overriden
}
//-- usage (i do it every time)
MyField mf;
UIController uiController;
if(mf instanceof UIController)
uiController = (UIController)mf;
} else { // use default impl.
uiController = new CommonUIController(mf);
}
我希望保持Field
,Controller
和宣布的关系彼此分开。就像这样C++可以做到:
//-- common.hpp
template<class _Controller, class _Field>
struct overriden_controller:
public _Controller
{
typedef _Controller controller_type;
typedef _Controller type;
typedef _Field field_type;
};
struct UrlEncoder{};
struct UIController {};
//-- MyField.hpp
// Field knows nothing about controllers
struct MyField {};
// !! Here comes association
template<>
struct overriden_controller<UIController, MyField>
{
// Overriden behavior
};
template<>
struct overriden_controller<UrlEncoder, MyField>
{
// Overriden behavior
};
//-- And then use associated value
auto controller = new field_controller<UIController, MyField>::type();
您能在这里提出什么建议?
通过将接口作为参数传递来获取类的实例似乎有点做作,除非您使用一些咬码编织来填充该方法,但是......
使用一些约定而不是配置,您可以实现如下内容:
public class AbstractField {
public Controller getController(Class clazz){
String name = clazz.getSimpleName();
String pack = clazz.getPackage().getName();
String controllerName = pack+"."+getClass().getSimpleName()+name;
Class<?> ctrl = null;
try {
ctrl = Class.forName(controllerName);
return (Controller) ctrl.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}