光学薄膜設計ソフトの設計 その21 - 変数実装の例 [考え中 - 光学薄膜設計]
光学薄膜計算エンジンの実装。始めたばかりでなかなかコードを書くところまで行かない。今回は、前回の変数のための抽象クラスを継承した実体のあるクラスを設計してみる。
従変数の例 - 誘電体の屈折率
OTFDependedVariableの具体的な派生クラスとして誘電体の屈折率の値を返すOTFDielectricModelRefractiveIndexというのを考えてみる。
@interface OTFDielectricModelRefractiveIndex : OTFDependedVariable { OTFVariable *lambda; const sellmeierCoefficients *coefficient; } + (NSArray *)modelNames; - (id)initWithModelName:(NSString *)mName withLambdaVariable:(OTFVariable *)lambdaVar; @endみたいなinterface。これはSellmeierの分散式を内部に持ってSiO2やTi2O5とかの材料の名前を与えると分散式を初期化して、主変数である波長を監視しながら、変更されれば分散式から値を計算すると言うものである。
クラスメソッドのmodelNamesは値が計算できる誘電体の名前を返す。
implementationは
static complex reflactiveIndex(const sellmeierCoefficients *coefs, double lambda); static const sellmeierCoefficients **coefficients; @implementation OTFDielectricModelRefractiveIndex // 材料の名前と係数を初期化するクラスメソッドは省略.... - (id)initWithModelName:(NSString *)mName withLambdaVariable:(OTFVariable *)lambdaVar; { unsigned int idx; self = [super init]; lambda = [super setDependOn:lambdaVar]; if ((idx = [modelNames indexOfObject:mName]) == NSNotFound) { [self release]; return nil; } coefficient = coefficients[idx]; return self; } - (void)dealloc { [super resetDependOn:lambda]; [super dealloc]; } - (void)updateValue { double lam = [lambda realValue]; val = reflactiveIndex(coefficient, lam); } @endinit...では指定された材料の名前からSellmeierの係数(の構造体)へのポインタを得るのと、波長の値を保持している主変数に対して、監視オブジェクトとして自分を登録している。材料の名前とその係数は、とりあえず簡単に、対応するものが同じ順番で並ぶように(名前はNDArrayの中で、係数は単なる配列として)初期化されているとする。実際に動くものを作るときはデータベース化する必要がある。
そしてupdateValueメソッドの中身を書いている。updateValueメソッドでは波長の値をとってきて、親クラスのインスタンス変数であるvalに屈折率の値をセットする。屈折率の値の計算はreflactiveIndexというCの関数で行っている。
親クラスであるOTFDependedVariableのメカニズムから、波長の値が変更されていればupdateValueが呼ばれて、値が更新されることになる。
なんとかこれでいけるじゃないでしょうか。継承関係がごちゃごちゃしてるけど、抽象性がFoundationよりずっと低いし、それにこういうのはFoundationフレームワークではよくあるパターンで、まあこんなもんだろ、ということで。
2009-01-19 23:40
nice!(0)
コメント(0)
トラックバック(0)
コメント 0