1

いくつかのFieldエンティティがあり、Controllerが次のように関連付けられています(Field,Generic_Controller <--> Specific_Controller)Specific_Controllerそれぞれの対応する関連付けFieldGeneric_ControllerJavaで実装したいと考えています。どうすればこれを達成できますか? コンパイル時間に優れています。

編集:これはタスクの擬似コードです(おそらくもっと明確になるでしょう):

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

getController現在、実装はありますが、DRY ではありません。コントローラー クラスと本体の同期を維持する必要があります。 それはおそらく問題を回避する可能性のある方法の1つでした(興味がある場合は、質問の最初のバージョンを参照してください)。

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();

ここで何を提案できますか?

4

1 に答える 1

0

インターフェイスをパラメータとして渡してクラスのインスタンスをフェッチするのは、メソッドにバイトコードを織り込んでいない限り、少し不自然に思えますが...

構成に関する規則を少し使用すると、次のように実装できます。

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;
    }

}
于 2012-12-01T02:37:00.313 に答える