倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

復習 & リファクタリング

API を簡潔にするためのリファクタリングと、(ちょっとブランクが空いたので)インターフェースの復習しましょう。

Simulator インターフェース


とりあえずシミュレーションを実行するインターフェース。

public interface Simulator{
    void simulate();
}

反復シミュレーション


ここでは「反復シミュレーション」のみを考えるという制限をしていたので、そのためのインターフェースを定義しておきましょう:

public interface IterativeSimulator
        extends Simulator, SimulationComponent{
    
    PhysicalSystem getPhysicalSystem();
    void setPhysicalSystem(PhysicalSystem system);
    
    Properties getInitParams();
    void setInitParam(String name, String value);
    void setInitParams(Properties initParams);
    
    Iteration getIteration();
    void setIteration(Iteration ite);

    List<ObservableSet> getObservableSet();
    void addObservableSet(ObservableSet obs);
    void removeObservableSet(ObservableSet obs);
}

Simulator インターフェース以外は以下で説明。

反復シミュレーションを構成するインターフェース・クラス


IterativeSimulator インターフェースを構成するインターフェース、クラスを見ていきましょう。 大まかに分類すると以下のよう:

  • ユーザーが実装を提供するインターフェース
  • データ管理に関するインターフェース
  • フレームワーク側が実装を提供するインターフェース
  • ネスト可能な要素

以前の定義に加えて、ここではそれらのうち幾つかが新たに「SimulationComponent」を拡張するようにします。 SimulationComponent インターフェースについては次回以降。

★ユーザーが実装を提供するインターフェース★

ユーザーが実装を提供する必要のあるインターフェースは、物理系を表す「PhysicalSystem」と観測量を表す「ObservableSet」です:

public interface PhysicalSystem extends SimulationComponent{
    
    void initialize(Properties initParams);
    void evolveState();

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    @interface InitParamEntry{
        Class<?> value();
    }
}
public interface ObservableSet extends SimulationComponent{

    PhysicalSystem getPhysicalSystem();
    void setPhysicalSystem(PhysicalSystem system);

    void observe(DataManager data);

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    @interface DataEntry {
        Class<?> value();
    }
}

★データ管理に関するインターフェース★

データ管理に関しては、観測量の値を管理する「DataManager」と、そこから値を取得するインターフェースが実装すべき「DataAccessor」を定義します:

public interface DataManager extends SimulationComponent{

    ObservableSet getObservableSet(int i);
    List<ObservableSet> getObservableSets();
    void addObservableSet(ObservableSet obs);
    void removeObservableSet(ObservableSet obs);
    
    boolean contains(String name);
    List<String> getDataEntries();
    Class<?> getDatatype(String name);

    Object getData(String name) throws ObservationException;
    void setData(String name, Object value);

    void resetData();
}
public interface DataAccessor {
    void setDataManager(DataManager data);
}

フレームワーク側が実装を提供するインターフェース★

フレームワーク側が実装を提供するインターフェースは、「反復」「反復条件」「観測量の値の出力」に関するものです。 これらは、ユーザー側から実装を定義することも可能です。

まずは「反復」に関するものから。 これには「IterationCondition」があります:

public interface Iteration 
        extends DataAccessor, SimulationComponent{
    
    IterationCondition getIterationCondition();
    void setIterationCondition(IterationCondition ic);
    
    Set<DataOutputter> getDataOutputters();
    void addDataOutputter(DataOutputter outputter);
    void removeDataOutputter(DataOutputter outputter);
    
    void execute(PhysicalSystem system);
    void evolve(PhysicalSystem system);
}

次は「反復条件」に関するもの。 これには「IterationCondition」があります(IterationCondition はインターフェースを少し変更):

public interface IterationCondition 
        extends DataAccessor, SimulationComponent{
    boolean evaluate();
}

最後は「観測量の値の出力」に関するもの。 これには観測量の値を出力する方法を表す「DataOutputter」と、出力するタイミングを列挙する「OutputTiming」があります:

public interface DataOutputter 
        extends DataAccessor, SimulationComponent{
    
    List<String> getEntries();
    void addEntry(String entry);
    void removeEntry(String entry);
    
    Set<OutputTiming> getOutputTimings();
    void addOutputTiming(OutputTiming timing);
    void removeOutputTiming(OutputTiming timing);
    void setOutputTiming(String s);

    void output()throws SimulationException;
}
public enum OutputTiming {
    INITIAL, AFTER_EVOLUTION, FINAL;
}

★ネスト可能な要素★

Iteration, IterationCondition はネストが可能なようにしておくと便利なので、そのためのユーティリティ・インターフェースとそれぞれのサブインターフェースを定義しておきます:

public interface Composite<E extends SimulationComponent>
        extends Iterable<E>{

    /** 子要素の個数に制限がない場合は Integer.MAX_VALUE を返します。 */
    int capacity();
    int size();
    
    void add(E child);
    void remove(E child);
    
    List<E> getChildren();
    E get(int i);
}
public interface CompositeIteration
        extends Iteration, Composite<Iteration>{}
public interface CompositeIterationCondition
        extends IterationCondition, Composite<IterationCondition>{}

Java魂―プログラミングを極める匠の技

Java魂―プログラミングを極める匠の技