著作一覧 |
dictionary.Add(data.key, data.foo + "," + ConvertBar(data.bar) + "," + data.baz); ...(幾つかのメソッドが間に挟まる) try { string d = map[input.key]; string[] data = d.Split(','); if (data[0] == input.Validation_key) { Command c = new Command("insert into ..." + data[0] + "','" + data[1] ... ... } } catch (NotFoundException e) { throw new ArgumentException(input.key + " not found"); } ...
なぜ、ここでCSVを使うんだ? dictionaryへ元のdataを突っ込めばいいだろ?
と激しく質問。
だって、ConvertBarするし、dataは読み取り専用だからbarのセッタが無いし、……し、……し……
だったら、使う場所でコンバートしたらどうだ?
dictionary.Add(data.key, data.foo + "," + data.bar + "," + data.baz); ... Command c = new Command("insert into ..." + data[0] + "','" + ConvertBar(data[1]) ...
これは等価だろ?
確かに……
で、これが等価だということは、
dictionary.Add(data.key, data); ... FooData data = map[input.key]; if (data.foo == input.Validation_key) { Command c = new Command("insert into ..." + data.foo + "','" + ConvertBar(data.bar) ...とも等価だよな?
(書いていて思ったが、Webアプリケーションのエスケープ問題と同根だな。なぜか変形した後のデータを保存したくなるらしい――ここでのinsert……は置いておくとして)
dictionary.Add(data.key, data.foo + "," + ConvertBar(data.bar) + "," + data.baz + "," + currentStatus); ...(幾つかのメソッドが間に挟まる) try { string d = map[input.key]; string[] data = d.Split(','); if (data[0] == input.Validation_key) { Command c = new Command("insert into ..." + data[0] + "','" + data[1] ... ... } } ...
はい?
いや、ステータスが追加になったんで……
なぜクラスを作らないんだ?
はて?
CSV作ってSplitするオーバーヘッドを考えたらクラスを作ったって同じだろ? (と、インスタンス生成のオーバーヘッドを言ってるのかと思った)
……(ぽかーん)
(あ、まったく考え付かなかったということか)たとえば
internal class FooWithStatus { internal FooData data; internal string status; internal DataWithStatus(FooData d, string s) { data = d; status = s; } } ... dictionary.Add(data.key, new FooWithStatus(data, currentStatus)); ...(幾つかのメソッドが間に挟まる) try { FooWithStatus fs = map[input.key]; if (fs.data.foo == input.Validation_key) { Command c = new Command("insert into ..." + fs.data.foo + "','" + ConvertBar(fs.data.bar) ... ...とするだけでも、全然ましだろ?
(すでに現実とは異なる展開)
あれ、妙に洗練されてきてるな?
internal class FooWithStatus { FooData data; string status; internal DataWithStatus(FooData d, string s) { data = d; status = s; } internal FooData Data { get { return data; } } internal string Status { get { return status; } } } ... dictionary.Add(data.key, new FooWithStatus(data, currentStatus)); ...(幾つかのメソッドが間に挟まる) try { FooWithStatus fs = map[input.key]; if (fs.data.foo == input.Validation_key) { Command c = new Command("insert into ..." + fs.Data.foo + "','" + ConvertBar(fs.Data.bar) ... ...せっかくのクラスだからちょっとカプセル化を意識してみました。
internal class FooWithStatus { FooData data; string status; internal DataWithStatus(FooData d, string s) { data = d; status = s; } internal string Status { get { return status; } } internal string Foo { get { return data.foo; } } internal string Bar { get { return ConvertBar(data.bar); } } static string ConvertBar(string s) { ... } } ... dictionary.Add(data.key, new FooWithStatus(data, currentStatus)); ...(幾つかのメソッドが間に挟まる) try { FooWithStatus fs = map[input.key]; if (fs.Foo == input.Validation_key) { Command c = new Command("insert into ..." + fs.Foo + "','" + fs.Bar ... ...はあ?
internal class Foo { FooData data; string status; internal DataWithStatus(FooData d, string s) { data = d; status = s; } internal bool IsInsertable(string s) { return data.foo == s; } internal Command createInsertCommand() { return new Command("insert into ..." + data.foo + "','" + ConvertBar(data.bar) ...); } static string ConvertBar(string s) { ... } } ... dictionary.Add(data.key, new Foo(data, currentStatus)); ...(幾つかのメソッドが間に挟まる) try { Foo foo = map[input.key]; if (foo.IsInsertable(input.Validation_key)) { Command c = foo.createInsertCommand() ...これで、呼び出し側はFooDataなんかについてそもそも意識する必要がなくなった。入力されたキーに一致するFooが存在して、しかもインサートすべき状態ならば、インサートするためのコマンドを作ってもらって、実行する。どのオブジェクトにどの役割を与えるかを決定して分離すること。これがカプセル化ということだ。
すさまくじ、おもしろい。と、ひっくりかえるくらにいおもしろい。
関数あたりは笑いを抑えるこたできないなぁ。途中、おれにはわけわかんないが、おもしろ過ぎてさらに最後で大爆笑。
こういうセンスってすげえ。
追記:あろはさんがまとめている。
追記の追記:斉藤さんのawk for Haskeller。
ジェズイットを見習え |
追記のリンクがおかしいようです。
どうもありがとうございます。直しておきました。