はじめまして、HN:Judaと申すものです。
このブログは、日々の思いつきや試行錯誤の後をつづることを旨としています。
ここに決定的な解答がかかれないこともままあると思いますが、そういうブログなのでご容赦を。
内容も情報技術やアニメ、マンガで気になるものをPickUpします。
長く続けられるようにゆるくやっていきます。
日々吾は
私が日々、情報技術に関して勉強したこと、試したこと、間違えてから試したことなど特に内容のないことの記録。
1/20/2020
3/31/2013
Commandパターン考
どうもJudaです。
Commandパターンでは、4つの役割で表現する。
Commandパターンでは、4つの役割で表現する。
- Command
- Invorker
- Receiver
- Client
図1. それぞれの包含関係を表す。 |
ClientはInvorkerに指令を設定することが主な役割である。InvorkerはClientから通知を受けて、Commandを管理し、任意のタイミングで起動させる。
ReceiverはCommandで行われる動作の主体となる。指令(Command)を受けるもの(Receiver)としての役割がある。
各役割の行う機能に関しては、いくつか曖昧な観点があると思う。
- Clientはコマンド自体を知ることがあるのか。
- InvorkerにはCommandの実行タイミングを決める権限があるのか。
- InvorkerとReceiverは同一でもいいのか。
1の場合には、ClientがCommandAをInvorkerに設定するということを明示的に知っているのかどうかになる。ClientとInvorkerの間にレイヤーが介在して、レイヤーがCommandの詳細を司ることも考えられる。
2の場合には、Invorkerがレイヤーの役割を果たしているのか、そもそもの起動を役割としているのかである。レイヤーの役割だと、呼び出すCommandをどう扱うのかは、Invorkerに委ねられていると考える。起動を直接Clientから指示される場合も含めての抽象化であるとも考えられる。
3. C#でのEventHandlerを考えると、CommandはEventであるが、Receiverに相当するものはEventHanlderを所有するインスタンスである。Clientは外部にあるが、InvorkerもEventHandlerを所有するインスタンスであり、ややこしい。抽象的に考えている場合には、InvorkerとReceiverが同じであっても構わない。しかし具体的に考えた時に、ここにCommandPatternがあると考えるのは、少々つらい。Callbackパターンとして考えるほうがより具体的である。
3/24/2013
開発者としての行き詰まりと対処方法
どうもJudaです。
プログラムの開発スキルに関して行き詰まっている感があるので、「CodeComplete 第2版 下 -完全なプログラミングを目指して」をまた紐解きました。
以前に読んだのは5年近く前なので、当時は「へぇ」という程度の認識であった部分も、今回は「あぁこれは確かに問題なる」という感じで、より身近に、そして具体的に理解できるようになっていました。
結論としては、コードレビュー、インスペクションなどのXPのプラクティスとテストによる相乗的な効果を期待して、それらのプラクティスを行なっていくことが当面の目標となりそうです。
今回、紐解いた部分は第5部 第20章 ソフトウェアの品質なのですが、今持っている問題意識に合致する部分がありました。
ユーザーが気にしている側面と開発者が気にする側面の2つを例に上げているのですが、この内の開発者が気にする側面を最近の自分は重視しすぎていると感じました。特に
プログラムの開発スキルに関して行き詰まっている感があるので、「CodeComplete 第2版 下 -完全なプログラミングを目指して」をまた紐解きました。
以前に読んだのは5年近く前なので、当時は「へぇ」という程度の認識であった部分も、今回は「あぁこれは確かに問題なる」という感じで、より身近に、そして具体的に理解できるようになっていました。
結論としては、コードレビュー、インスペクションなどのXPのプラクティスとテストによる相乗的な効果を期待して、それらのプラクティスを行なっていくことが当面の目標となりそうです。
今回、紐解いた部分は第5部 第20章 ソフトウェアの品質なのですが、今持っている問題意識に合致する部分がありました。
ユーザーが気にしている側面と開発者が気にする側面の2つを例に上げているのですが、この内の開発者が気にする側面を最近の自分は重視しすぎていると感じました。特に
- 保守性
- 可読性
- テスト性
- 理解性
の4項目に関しては常に問題意識を持ち、取り組んでいました。
テスト性の重要性に関しては、実際にテストを構築する体制に切り替えていこうという意識の中で、設計レベルで考えていないと障害を強く感じることに気が付きました。JUnitやNUnitなどのxUnit系列のテストフレームワークの使い方に多少ながら習熟するのですが、肝心のテストそのものが暗中模索であることに直面しています。
またこの葛藤に並行して、テストを容易にするために、より多くの割り込みを行えるポイントを足すことを考えました。そして依存関係に対する割り込み可能性の留保や抽象レイヤーを意図的に作って階層化を図るなどをして、理解性にも取り組んでいるつもりです。ただしこの点に関して、適切な抽象化、適切な階層化のバランスが掴みづらく、最近はオーバーエンジニアリングの感が否めません。僅かな実装でいいのに、それ以上に手の込んだ実装を行なっていると思っています。
一方で可読性、保守性は、開発者として仕事を受ける以前から、「実装するよりもデバッグするほうがより能力が必要である」という主旨の警句を信条に、より簡潔に、より明確に取り組んでいるつもりです。自分自身がソースコードをより速く頭から追い出して、より速く頭に入れられるようにすることがそれに合致すると感じています。
現在の取り組みは以上のような感じではあるのですが、ユーザー側からの要求にうまく応えていると感覚が乏しくなっているように感じます。外部品質であるところの
- 正当性
- 使用性
に関して、現在の仕事上の取り組みから十分対価に見合っているという感じが薄いのです。
内部品質と外部品質は互いに独立しているわけではないので、相互に作用をしているし、一定レベルから影響をしだしたりなど、いくつかの数値を元にCode Completeでは説明されています。なので私はちょうどレベルとレベルの間でうまく壁を超えられない状態なのではないかと推察しました。そのため、この壁を超えるためには、ある程度の経験と修練がいります。でも何に打ち込み、何に慣れなければならないのかは判然としません。そしてテストに関しては、大きな期待を抱いていました。しかしCodeCompleteでは、テストのみによって達成される品質向上は心もとないと言っています。品質向上の1指標であるカバレッジに関しては、否定的な結論が書かれていました、あくまで単一のプラクティスとしてテストを行った場合ですが。
ここで強調したいのは、CodeCompleteで指摘されているのは、自動テストに向いているものと人間の手によって行われるのに向いているテストがあるということです。ここで引き合いに出されていたのはXPで行われるようなコードレビューやコードインスペクションでした。それぞれ特性があり、向き不向きがあるのですが、組み合わせることによってより高い品質へ到達できることが結論として挙げられています。
なので、今後の方針としては、テストに関しての試行錯誤と並行して、他に同様な問題意識のある同僚などを巻き込みつつXPのプラクティスをおこなっていくことになりそうです。
11/26/2012
Android DatabaseでのSQLiteStatementについて
AndroidのDatabaseを使う際に、SQLiteDatabase.compileStatementメソッドでSQLiteStatementを生成する方法がある。これは、実装上Insert,Update,Replace,Deleteのためのものではなく、あくまでそれ以外の呼び出し、Create/Drop Table, View , Indexを呼び出す際に利用するものとJavaDocに記述されている。
SQLiteStatementのオブジェクトはSynchronaizedなので、他のスレッドと共有でつかうことはできない。また内部のBind処理に関して、利用が終了した時点でClearBindArgsを呼ばないとクリアされないので、その動作が関係しているのではないかと推察する。
またSQLiteStatementを利用しなくても、execSQL(String)と等価であるとあるので、CreateTableでは利用しないし、DropTableでもSQLiteStatementはあまり利用しないとおもわれる。Bindする要素がなく、そのSQLを隠蔽したい場合にのみ使うとかんがえられる。そしてViewの場合に利用することが多くなりそうである。ViewのSQLを作成しておいてBindを行い、利用する局面はありうる。
追記
JavaDocには、COUNT(*)などの場合の呼び出しに使う場合が記述してある。
追記
SQLiteStatementのクラスJavaDocコメントを以下に引用する。
SQLiteStatementのオブジェクトはSynchronaizedなので、他のスレッドと共有でつかうことはできない。また内部のBind処理に関して、利用が終了した時点でClearBindArgsを呼ばないとクリアされないので、その動作が関係しているのではないかと推察する。
またSQLiteStatementを利用しなくても、execSQL(String)と等価であるとあるので、CreateTableでは利用しないし、DropTableでもSQLiteStatementはあまり利用しないとおもわれる。Bindする要素がなく、そのSQLを隠蔽したい場合にのみ使うとかんがえられる。そしてViewの場合に利用することが多くなりそうである。ViewのSQLを作成しておいてBindを行い、利用する局面はありうる。
追記
JavaDocには、COUNT(*)などの場合の呼び出しに使う場合が記述してある。
追記
SQLiteStatementのクラスJavaDocコメントを以下に引用する。
A pre-compiled statement against aSQLiteDatabase
that can be reused. The statement cannot return multiple rows, but 1x1 result sets are allowed. Don't use SQLiteStatement constructor directly, please useSQLiteDatabase.compileStatement(String)
SQLiteStatement is NOT internally synchronized so code using a
SQLiteStatement from multiple threads should perform its own synchronization
when using the SQLiteStatement.
基本的にはViewとしても使えないと考える。MAX、MINやCOUNTなどの特別なProcedureでの利用が主なようだ。AndroidでのDatabase処理でinsertOrUpdate
Android:Is there a better way to insert and/or update a database entry?
AndroidのSQLiteのSQLiteDatabaseの動作は、insertとupdateが明確に分離している。
これ自体は、必ず新しく追加したい、必ず更新したいという動作をするときに必要になる。しかしながら、項目があれば更新なければ追加という動作を行いたい場合がある。これに関しては上記の質問の回答である。REPLACEを使えばよい。
SQLiteDatabase.replace
もともとSQLiteにはReplaceが特別な動作として定義されている。他のテーブルの場合には、INSERT IF CONFLICT や INSERT OR UPDATEがあったりしたと思った。
AndroidのSQLiteのSQLiteDatabaseの動作は、insertとupdateが明確に分離している。
これ自体は、必ず新しく追加したい、必ず更新したいという動作をするときに必要になる。しかしながら、項目があれば更新なければ追加という動作を行いたい場合がある。これに関しては上記の質問の回答である。REPLACEを使えばよい。
SQLiteDatabase.replace
もともとSQLiteにはReplaceが特別な動作として定義されている。他のテーブルの場合には、INSERT IF CONFLICT や INSERT OR UPDATEがあったりしたと思った。
登録:
投稿 (Atom)