FC2ブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[Android] オブジェクトの粒度について

最近、同僚の書いた Android アプリケーションのコードを見て、こちらの記事を書いた。

もっと書きたくなってしまったので、本来は備忘録だったはずのこのブログに、さらに書いておくことにしてみる。



彼自信は自身のコードにご満悦の様子なのだが、そのコードを読んでみたら、ついついダメ出しをしたくなってしまった次第だ。

メインの Activity のコードが 2000行を超えており、その他の .java が10本ほど。
その他の .java は、アダプタ派生クラスなど、ちょっとしたもので構成されており、それぞれ10行程度から多くても100行程度。
という構成だった。

たしかに、彼の作ったアプリケーションは、メインActivityでタブを切り替えて使うタイプのもので、メインActivityに処理が集中しがちなのは認める。

だが、集中したその処理を全てメインActivityの中だけで処理して、満足げな顔をしていてはダメだ。

全然ダメだ。





例えば、それなりに多い情報を ListView で表示しているのだが、単にアダプタの派生クラスを作ってそれでおしまいにしている。

当然ながら、アダプタでやっていることは、本来アダプタでやることだけだ。
つまり、独自データ構造から、ListView行用のViewに配置された各GUIパーツにデータを渡すという作業だ。

それは全然いいのだが。

1行あたり、結構な情報量のリストなわけなのに、1行あたりのデータの管理を、全部メインActivityでやっている。

これが、ダメだ。

もっと小さいアプリケーションなら、問題ないと思う。
だが、メイン2000行 に対して、そのアダプタが10から100行程度ではいけない。

ここはひとつ、そのListViewが司るデータ全般を、ListView自身にまかせるべきだろう。

幸いなことに、というか、極めて当然なことに、Android Java では標準のListViewから独自クラスを派生させて、それを、.xml に記述できる。






つまりこういうことだ。
***** MyHogeListView.jaba *****

public MyHogeListView extends ListView {
public void initializeListView(Activity activity, ArrayList<重要データ> hoge) {
MyHogeAdapter adaper = new MyHogeAdapter(activity);
...アダプタへのデータ追加...
}
public void hogeHogeHoge() {
...メインActivityから、何らかの状況で呼ばれて、何らかの処理をする...
}
public void fugaFugaFuga() {
...メインActivityから、何らかの状況で呼ばれて、何らかの処理をする...
}
}
class MyHogeAdapter extends ListAdapter<重要データ> {
...一般的なアダプタのあれこれをする...
}
// ひょっとすると、Javaでは非staticな内部クラスとして MyHogeAdapter を定義できたかもしれないが、ここではそれは論じない



Adapter だけではできなかった(又は、できたとしても、美しくできなかった)諸々のことを、ListView 派生クラスを作ることによって、全てカプセル化するのだ。

.xmlにも、このカスタムクラスを直接記述できる。
たとえば、

<jp.co.hoge.hogeapplication.MyHogeListView attrib="hoge">
</jp.co.hoge.hogeapplication.MyHogeListView>

といった具合に。



カプセル化って何?とか言う人もいるかもしれないが、オブジェクト指向の重要な要素のひとつ(のハズ)だ。

Androidプログラムの規模だと、この程度のオブジェクトの粒度がちょうど良いという気がしている。(将来は分からないが)




さらに言うと、上記のようなリストがいくつかあって、それぞれ同じ ArrayList<重要データ> を扱いながらも、結構違った表現でエンドユーザーに表示する、といったパターンもあるだろう。

その場合は、迷わず共通基底クラスを用意することを考えるべきだ。

つまりこういうことだ。

public MyHogeListBaseView extends ListView {
...各派生クラスでの共通変数を持つ...
...各派生クラスでの共通メソッドを持つ...
}


public MyHogeListBaseViewSuper extends MyHogeListBaseView {
...このクラス独自で行うメソッドを持つ...
...なんだったら、このクラス独自で持っておきたい変数を持つ...
public void onCreate(...) {
このクラス用のListViewに対してArrayList<重要データ>を使って初期化する。
}
}


public MyHogeListBaseViewUltra extends MyHogeListBaseView {
...このクラス独自で行うメソッドを持つ...
...なんだったら、このクラス独自で持っておきたい変数を持つ...
public void onCreate(...) {
このクラス用のListViewに対してArrayList<重要データ>を使って初期化する。
}
}






ListView 派生クラスに限ったことではなく、Activity でもそうだ。

例えば、とあるアプリケーションで、全ての画面に「終了」ボタンがあるとしたら、迷わず共通基底クラスを作るべきだ。


public MyBaseActivity extends Activity {
@Override
public void onCreate() {
super.onCreate();
...終了ボタンのクリックリスナー登録...
}
public void クリックリスナー() {
...アプリケーション終了処理...
}
}


public MyOtherHogeActivity extends MyBaseActivity {
...このActivity固有の処理...(終了ボタンの処理はいらない)
}


public MyOtherFugaActivity extends MyBaseActivity {
...このActivity固有の処理...(終了ボタンの処理はいらない)
}





このことも、オブジェクトの粒度を適切に保つために有効な手段である。
スポンサーサイト
コメント
コメントの投稿
管理者にだけ表示を許可する

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。