ありぷらなネタ的には、weekpointer あたりをカプセル化して、LINQ の遅延実行風に、実際の参照時に中身を取ってくることができる。例えば、ストリーム的に流れてくる計測データの大半を捨てて、UI の都合で定期的にピックアップ表示する感じ。
— Tomoaki Masuda (@moonmile) 2016年9月14日
な感じで、内部データを遅延して持って来る例を作ってみる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | class Program { public static List<Cat> cats = new List<Cat>(); static void Main( string [] args) { cats.Add( new Cat( "tora" )); cats.Add( new Cat( "mike" )); var pradaRed = new Prada(); var pradaBlue = new Prada(); var pradaYellow = new Prada(); Console.WriteLine( "1: {0}" , pradaRed.Cat?.Say()); Console.WriteLine( "2: {0}" , pradaRed.Cat?.Say()); Console.WriteLine( "3: {0}" , pradaBlue.Cat?.Say()); Console.WriteLine( "4: {0}" , pradaYellow.Cat?.Say()); return ; } } class Cat { string _name = "" ; public Cat( string name) { _name = name; } public string Say() { return $ "{_name}: nya-" ; } } class Prada { Cat _cat = null ; public Cat Cat { get { if (_cat == null ) { _cat = Program.cats.FirstOrDefault(); if (_cat != null ) { Program.cats.Remove(_cat); } } return _cat; } } } |
実行するとこんな感じ
意味合いとしては、アリスはプラダのバックを3つ持っている(pradaRed、pradaBlue、pradaYellow)んだが、中に猫がはいってるかどうかは分からない。どの順番で開ける猫がいるかわからないし、猫がいるかどうかも知らない。でも、開けると猫が入っているか、また猫が入ってないかわかる。というシュレディンガーなプラダな猫の話。
cats は最初から用意されているので、外部データとして存在します。メインプログラムのアリスから見れば、最初は、Prada のオブジェクトを作るだけなので、内部の _cat が存在するかどうかは知らない。というか、知らなくてもいい状態。Cat プロパティを呼んだときにはじめて、中の cat を取り出すことができる。鞄クラスの Prada から見える Cat プロパティは、外部からみれば単純にデータを返しているように見えるが、実際は別に用意されている cats から取り出している。
つまり、MVVM パターンでいえば、View が VM に対してプロパティアクセスでデータを取り出しているときに、VM は Model からデータを引っこ抜くわけだが、そこは View が VM に問い合わせたときまで遅延される方式になっている。MVVM の大抵の例は、Model が省略されていて、View から VM のアクセスしかないのだが、ここで VM と Model との違いが明確になるよという話だ。
こんな感じで MVVM パターンを使える。Model は常に VM から参照される「制限」を付けることで、MVVM パターンの役割が担えるということだ。
じゃあ、Model(データベースや計測器など)からデータが上がってくるようなときはどうするのか?ってのは別パターンを使うことになる。この話は別の記事に書くことにしよう。