1.はじめの状態
MainActivity の onCreate に直接 DB アクセスのプログラムを書いておりました。データベースから SELECT したレコードは、データクラスに格納しております。
2.メソッドへ抽出
MainActivity の onCreate に直接書いていた DB アクセスをメソッドに切り出し、抽出いたしました。
3.DB アクセスクラスの作成、メソッドをそこへ移動
MainActivity クラスに置いていた DB アクセスメソッドを専用の DB アクセスクラス、つまり DAO のクラスを作り、そこに移動いたしました。
テーブルを表す DAO クラスにするか、機能・用途に合わせた DAO クラスにするか、悩みどころです><。
今回は、複数テーブルをまたがった機能はないため、テーブルごとに DAO クラスを用意いたしました。テーブルを JOIN してデータアクセスする機能が必要となったら、テーブルごとの DAO はそのままに、機能に合わせた DAO を作ればよいと考えますの。
具体的には、次のようにいたしました。
- パッケージ名:dao
- DAO クラス名:テーブル名 + Dao。テーブル名はキャメルケースに変換
- フィールドには SQLiteDatabase を持たせ、コンストラクタでセットする。
- SELECT、UPDATE、DELETE などの DB アクセスに関するメソッドを作っていくが、引数や返却値には積極的に DAO に対応するデータクラスを使用していく。
4.DB へ渡す、受け取るデータを扱うクラスの整理
アプリでデータを一塊にしたクラス、データの実態クラス、エンティティクラスは作っておりました。しかし、整理しておらず、見通しが悪いですの><。
そこで、パッケージを作ってそこに移動させ、ファイル名クラス名を修正いたしました。
- パッケージ名:entity
- クラス名:テーブル名を単数形にしたもの。キャメルケースに変換する。
【例】テーブル名:employed_people ならばクラス名は、EmployedPerson
5.Singleton パターンにする。
DB アクセスのヘルパークラスを複数インスタンス化しなければならない理由はございません。スレッド処理をして、同時に並列に DB アクセスする必要もございません。
いくつもインスタンス化したままでも問題は発生しておりませんが、次のようなエラーの報告もございます。
そのため、シングルトンパターンにして、DB アクセスヘルパーのインスタンスはひとつだけ作られるようにしておきました。
修正箇所は参考ブログページを見ていただくとして、ポイントは次のようになりました。
- ヘルパークラスで、自分自身のフィールドを private static で作る。
- 自分自身のフィールドには初期値として明示的に null を設定しておく。
- ヘルパークラスのコンストラクタは private に変更する。
- ヘルパークラスのインスタンス化メソッド(getInstance)の宣言は、public static synchronized として排他制御を付ける。
- ヘルパークラスを使用する別クラスではインスタンス化する場所を、ヘルパークラス名.getInstance(context) に書き換える。
クラスをインスタンス化するメソッド宣言に、「synchronized」をつけると良いそうですが、なんのことよく分かりません><。。。ので、調べました。
スレッド処理を念頭に synchronized が使われる事がわかりました。DB アクセスインスタンスが実行中は他のクラスなどからインスタンスに処理要求が来ても待たせる、排他制御をする、という理解でよさそうです。
次のページがわかりやすかったですの♪
おわりに
テキトーにプログラミングしていましたら、次の日見たら何をしているのかわからなくなるようなソースになっておりました><。
今回は、そんなソースの整理、リファクタリングについてですの♪少しは見通しが良くなったかしら♪
ContentProvider を使うように修正するのが次のステップかしらね♪
なお、排他制御、スレッドについての参考ページは今後 Android アプリを作っていく中で活用することも多そうです。良いページに出会えたこと、嬉しく存じます。
以上です。