2009-12-29
staticとinstanceと。
弊社の新人のブログより。
わたしの中で、概念的なものはわかっているのですが、実際に自分で使い分けろと言われてもどういう時に使い分けたらいいのかがわからないのでパッとしません。。。。
会社の先輩が書いたソースをみると、共通処理をクラスメソッドにしています。
でも、共通処理でもクラスメソッドにできないものもあるみたいで・・・・・。
インスタンスとクラス - yumicroの日記
これについて考えてみました。
この新人が配属されている部署から考えて、ズバリ「先輩に聞いて先輩が言った通り作る」がベストな訳で、でもそうすると話が終わってしまうのとSIerと呼ばれる企業の黒い部分をいろいろ掘り起こさなくてはならなくなるのでやめましょう。
クラスフィールド、クラスメソッドとインスタンスフィールド、インスタンスメソッドの使い分けは、クラス設計とかコード設計と呼ばれる作業になります。SIerの仕事の仕方だと基本的に設計は実装の前工程として行われ、設計が完了してから実装に入るという通例がありますが、このクラス設計やコード設計に限って言えばほぼ実装と同じタイミングで行われるんではないか、と思っています。理由は簡単で、事前に要件が満たせるしっかりしたクラス設計をする事が難しいせいです。
そういう意味では、新人ながらなかなか難易度の高い所に着目しましたね。
クラスなんちゃらとインスタンスなんちゃらについて、このエントリを書く前にぐーぐる先生や自称OO厨の友人を通じて再度自分なりに勉強をしてみましたが、オブジェクト指向プログラミングにこだわるのかトランザクションスクリプトとして作るのか、によってどのような機能をクラスなんちゃらにするのかが左右されますが、基本的にSIerで作るアプリケーションの場合、どちらであっても記述するコードのバリエーションにはさほど差異はないのではないかとも思います。
あとはどのコードをどのクラスに持たせるか、持たせるならstaticなものとして持たせるのかインスタンスに紐づくものとして持たせるのか、という事を考えていきます。僕の過去の実装を振り返って整理してみると、以下のような基準でクラスなんちゃらにするかインスタンスなんちゃらにするかを決めていたように思います。
| クラスフィールドにするもの | インスタンスフィールドにするもの |
|---|---|
| アプリケーションの中で1つのインスタンスとして持ちたい | インスタンスごとに存在するインスタンスを持ちたい |
| 複数のオブジェクトに対して同一のインスタンスを提供したい | 無関係なインスタンスには参照させたくない |
| アプリケーション内定数 | 非定数 |
メソッドに対しても同様に整理しています。
| クラスメソッドにするもの | インスタンスメソッドにするもの |
|---|---|
| 引数以外に振る舞いを変える要因がない | 引数以外に振る舞いを変える要因がある |
| クラスフィールドに対する操作 | インスタンスに対する操作を行う |
特に「引数以外に振る舞いを変える要因がある/ない」という点が重要だと思っています。
インスタンスフィールド、インスタンスメソッドにするという事は、使うためにインスタンスを生成する必要があるという事です。インスタンスを生成するにはnew演算子を使ってコンストラクタを使いますがそのコンストラクタの中にも制御ステートメントが書かれていたりしてそれなりに実行コストが発生していたりします。
転じて、クラスフィールド、クラスメソッドはクラスそのものに紐づく為、ある種のコスト(クラスローダでロードされるコストやグローバル変数化して影響範囲が見えづらくなるリスク)はあるものの基本的には即利用可能です。
インスタンスフィールドによってメソッドの戻り値が変わる場合や、継承を用いて同じメソッド名、同じ引数(シグネチャと言います)だけど違う機能にするいわゆるオーバーライドを用いる場合などは、このインスタンス生成のコストを踏まえてもインスタンスメソッドとしなくてはなりません。
反面、クラスメソッドは継承によるオーバーライドを使えませんし、クラスフィールドによってメソッドの戻り値を変化させる事はできますが、インスタンスのそれと違って持てるバリエーションに制限があります。
メソッドを拡張する必要があるかないかは、そのメソッドをどういう意図で追加しようとしているのかによりけりなので、一定のルールを示して「これで決まり」と簡単に言えないのがこの設計という工程の大変なところです。
この件で意見を聞いた自称OO厨は、「原則インスタンスフィールド、インスタンスメソッドで、いくつかの条件を満たさない限りクラスフィールド、クラスメソッドは作らない、というルールを持っているそうです。
こういったルールがチーム内にあるのであれば、僕が書いたような事を一切無視してそのルールに従うというのが企業内プログラミングのある種の「鉄則」だったりする訳ですが、ルールを作る必要が出た場合に意見を言えるようにしておく、ルールが間違っていないか検証できる目を持つという意味では知っておいて損はない事です。
クラス設計についてのエントリはOO厨にフルボッコにされる危険を伴なう(実際ジャブは既に食らったw)のと個人的にそこまで強い思い入れがある訳ではない分野という事もあって、なるべく避けていたんですが、可愛い新人の為に勇気を振り絞ってみます。
- 6 http://twitter.com/
- 3 http://reader.livedoor.com/reader/
- 2 http://b.hatena.ne.jp/backpaper0/
- 2 http://brizzly.com/
- 2 http://www.google.co.jp/reader/view/
- 2 http://www.google.com/reader/view/
- 2 http://www.movatwitter.jp/url?friend=yusuke1118&url=http://d.hatena.ne.jp/imai78/20091229
- 1 http://a.hatena.ne.jp/a-conv/mobile
- 1 http://a.hatena.ne.jp/kazuki-aranami/
- 1 http://b.hatena.ne.jp/entry/d.hatena.ne.jp/imai78/20091229/1262102470






