なんちゃってMathematicaを作る - その18 [なんちゃってMathematica]
なんだか週一回ペースになってる「なんちゃって」シリーズ。前回は3種類の座標を使って順番に変換することでプロットを作成することにして、その3種類の座標が混在してもいいとして文字なんかのシンボルの配置を簡単にできるようにしようと考えた。その結果発生する問題について整理した。今日はその座標の変換の表現方法について。
そういうのをどう実装するかというと、いくつかの方法がある。
サブクラス化は、
それぞれのクラスは簡単になって、座標の変換は別のサブクラスを作るという作業に置き換えられる。これはシンプルだけど、これらの座標を保持するNSArrayなどは、インスタンスを切り替えないといけない。これは内部の隠蔽という観点からは美しくない。
それ以外の方法があるか、というと
しかしこれでは座標点の挿入削除は全部自分で実装しないといけないし、ライブラリのユーザからは使い慣れたNSArrayなんかが使えない、ということになる。
たとえば曲線オブジェクトを、plot座標が詰まったNSArrayで表現したとする。この曲線オブジェクトをnormalized座標に変換したとする。plot座標のほうを保持していたNSArrayはnormalized座標を保持するように付け替えないといけない。もしこの作業を明示的にしないといけないとすると、これはすっごいイマイチ。
この場合はそれよりも曲線オブジェクトごと座標変換される、というふうにすべきである。つまりplot座標からnormalized座標に変換するメソッドはNSArrayも受け付けるようにする。たとえば変換のメソッドが
NSArrayのカテゴリを作って、このメソッドを受けるようにする。このメソッドのなかでは
4.5 座標の入れ替え
実装のレベルの話に近くなるけど、Plot → Normalize → Viewと、座標が変換される過程をユーザが知る必要はないし、コードの上からも座標がどう表現されているか、を知る必要はあまりない。したがって座標は外から見ればただの一般的な座標でその種類はあらわには見えないようにしておいたほうがいい。そういうのをどう実装するかというと、いくつかの方法がある。
- 座標の種類と、座標値を保持するunion
- 一般座標のサブクラスとしてそれぞれの座標を定義
- その他
@interface CPCoordinate : NSObject { int type; union { plotCooridnate plotc; normalizedCoordinate normc; viewCoordinate viewc; } cooridante; }みたいなかんじ。オブジェクト自身が中身を認識して切り替える、というもの。愚直で問題はでにくいが、コードが汚くなりがちである。
サブクラス化は、
@interface CPCoordinate : NSObject @end @interface CPPlotCoordinate : CPCoordinate { double x; double y; } @end @interface CPNormalizedCoordinate : CPCoordinate { float x; float y; } @end @interface CPViewCoordinate : CPCoordinate { NSPoint pos; } @endみたいな感じ。
それぞれのクラスは簡単になって、座標の変換は別のサブクラスを作るという作業に置き換えられる。これはシンプルだけど、これらの座標を保持するNSArrayなどは、インスタンスを切り替えないといけない。これは内部の隠蔽という観点からは美しくない。
それ以外の方法があるか、というと
- 座標クラスとそれを保持するクラスを一体化する
しかしこれでは座標点の挿入削除は全部自分で実装しないといけないし、ライブラリのユーザからは使い慣れたNSArrayなんかが使えない、ということになる。
4.5.1 具体的な方針
やはり簡単なのはサブクラス化だろうな。この方向の問題は、変換前の座標を指しているオブジェクトは、変換後の座標のありかを知らないといけない。たとえば曲線オブジェクトを、plot座標が詰まったNSArrayで表現したとする。この曲線オブジェクトをnormalized座標に変換したとする。plot座標のほうを保持していたNSArrayはnormalized座標を保持するように付け替えないといけない。もしこの作業を明示的にしないといけないとすると、これはすっごいイマイチ。
この場合はそれよりも曲線オブジェクトごと座標変換される、というふうにすべきである。つまりplot座標からnormalized座標に変換するメソッドはNSArrayも受け付けるようにする。たとえば変換のメソッドが
- (id)plotToNormalizedWithTransformation:(CPTransformation *)transform;みたいなものだとする。
NSArrayのカテゴリを作って、このメソッドを受けるようにする。このメソッドのなかでは
- 新しいNSArrayを作る
- 自分が保持しているオブジェクトに同じメソッドを投げる
- オブジェクトが返した変換後のオブジェクトを新しいNSArrayに加える
- 新しいNSArrayのほうを返す
2012-02-19 22:01
nice!(0)
コメント(0)
トラックバック(0)
コメント 0