Posts Tagged ‘ 仕様

チップの登録機構

どうも、お久しぶりです。テストがあったり、私が所属してる情報工学科に革命がおこったりで色々ごたごたしてまして落ちつて作業できる時間が少なくて、更新できてなかったです。どんな革命が起きたかはここで語ることじゃないので、控えておきますが。

さてタイトルのことですがこれはかなり悩みに悩みました。
この前書いたとおりこのプロジェクトはプラグインに対応させるつもりです。ですのでできるだけ外から追加できる拡張性をもったコードを書かなければならず、 しかもこのチップの部分はこのプログラムの中核の部分なので手は抜きたくありませんでした。

デザインパターンをあたってみて、「あ、これ使えるじゃん!!ふむふむ、え~っとこうやって、これがこうで… で、肝心なここは……使えねぇ!!!!!」的なことの連発でした。

どうにかならないか困り果ててとつぶやいたら@haxeさんから回答がいただけました。

kassyi
@kassyi
@haxe
クラスを条件によって作り分けたいんです。例え話にすると調査員という仕事があり、Aは0歳から9歳までの朝食の食べる量を調査する、Bは14~50歳までの歩数を調査する。AとBが調査員というクラスを継承しているとすると、どうすればインスタンスを作り分けられるかって話です。
link
kassyi @kassyi @haxe 普通に考えれば
if(age >= 0 && age <= 9)
retrun new A();
else if(age >=14 && age<= 50)
retrun new B();
となると思うのですが、これだとプラグインなどで調査員を追加するのが難しくて。。
link
kassyi @haxe @kassyi 今WebRequestクラス見てるので、お勧めするのはその方法かなぁ。 http://msdn.microsoft.com/ja-jp/library/system.net.webrequest.aspx link
haxe @haxe @kassyi ちなみに標準機能はどこかで初期化するとして、利用者が派生クラスを追加する際に、app.configから登録できるようにしておくとさらに吉。 http://msdn.microsoft.com/ja-jp/library/42z9z1b9.aspx link

このやり取りのおかげ様でやっとこさ整合性のとれたコードを書くことができました。書いたコードをざっとまとめるとこんな感じです。

すべてのチップはこのCihpクラスを継承して表現されます。また継承されたクラスのコンストラクタはprotectedにして直接はインスタンスが作れないようにします。で、どこからインスタンスが作れるかというとChipクラスのCreate()です。そのCreate()の中で何をやってるかというと、登録された派生クラスのクリエイター対して「このIDのチップ扱える?」って順繰りに訪ねて行って扱えるなら「インスタンスを頂戴ね」ということでクリエイターにインスタンスを作らしています。

…ってなことで、なんとかえっちらおっちら拡張性のあるチップ登録機構を作ることができました。いやーまさかWebRequestクラスをまねできるとは思いませんでした…。.Netライブラリは当然プログラマーのプロの人が書いているので吸収できるところは吸収するようにしようと思いました。@haxeさんに、感謝。

プロパティに構造体を…

struct R
{
    public int foo;
}

class Class1
{
    public R hoge { set; }
}

class Program
{
    static void Main(string[] args)
    {
        Class1 class1 = new Class1();
        //エラー
        class1.hoge.foo = 5;
    }
}

激しくこういうことがしたい。なんで構造体をプロパティにできない?いや、もちろんできるんだけど、コードのように代入することができない。同等のことをするんだったら

static void Main(string[] args)
{
    Class1 class1 = new Class1();
    R r = class1.hoge;
    r.foo = 5;
    class1.hoge = r;
}

こうとでもしないといけない。まどろっこしいなぁ…。

追記:

ピンバックを送ってくださった方がいます。そちらになぜできないかが書いてあります。結構納得しました!