cafegale(LeafCage備忘録)

LeafCage備忘録(はてなダイアリー)と統一しました。

オブジェクトは出来るだけ作りたくない

私のプログラミングのスタイルなのだが、オブジェクトというのはあまり使わず、手続き的に記述して、リファクタリング時に何となくまとめた方が見通しが良くなるものをオブジェクトへとまとめるという作り方をする。
オブジェクトはファイルシステムで言うフォルダ(ディレクトリ)のようなものだ。
まとめた方が混乱しないものだけをまとめる。
だからオブジェクトは初めから作られたのではなく結果として生まれる。

ファイルシステムについても、フォルダを作るときというのは、細かいファイルをまとめるときというのが主だ。初めからカテゴリ分けしたフォルダを作るときもあるけれど、その場合初めからどういうカテゴリ分けが適切かを知っておかないと、無駄なフォルダを作ったり、ディレクトリ階層を作ってしまうとその構造が根本的に間違っていることに後から気付いたりするものだ。

私がオブジェクトをあまり好きでないのはオブジェクトはブラックボックスのようなものだからだ。
オブジェクトが増えると一体何が行われているのか把握できなくなる。
見通しを損ねないバランスで作らないといけない。

他にもオブジェクトはオーバーヘッドが大きいとか、記述が面倒とか、小さい処理でオブジェクトを使うには大げさすぎるというのもある。

オブジェクトを使うという判断は遅延でいいと思う。
初めから使うと考えずに、必要に感じてきたときに初めて考えるみたいな。
トップダウンで考えるのでなくボトムアップで。

私はオブジェクト指向にあまり触れていないから、初めからオブジェクト指向で設計することが出来ないというのもある。
オブジェクト間の相互作用とかもよく分かっていない。

オブジェクトAからオブジェクトBへメッセージングするとき、オブジェクトAのコンストラクタやらメソッドやらでオブジェクトBを作る/呼ぶしてからそのオブジェクトBのメソッドを呼ぶのだろうけれど、包含関係がなくてもオブジェクトBがオブジェクトAの中に入ることになるのがとても気持ち悪い。

だからなるべくオブジェクトの中に包含関係がないオブジェクトを入れるみたいな構造を作りたくない。

私にとってオブジェクトとは、初期化時に引数をあらかじめ幾つか渡していたら、そのオブジェクトのメソッドで渡す引数が少なくなって見やすいという程度のものである*1

余談:ファンがシンガーに「歌って」とメッセージングするのなら
public class Fan {
  public static void main(String[] args) {
    Singer singer = null;
    if("wada".equals(args[0])) {
      singer = new WadaAkiko();
    } else {
      singer = new MichaelJackson();
    }
  singer .sing();
  }
}

こんなんじゃなく

fan = new Fan();
singer = new Singer();
fan.send(singer, "sing");

こうなるべきだろ(イメージ的に)
または

fan = new Fan();
singer = new Singer();
fan.send_sing(singer);

こうなるべきだろ。

だってfanはsingerを包含してないんだもの。
外部から引数として受け取って一時的に保有するのが概念的に正しいだろ。

これなら外側から登場人物(オブジェクト)がfanとsingerがいるなということが分かる。
それがメソッドやコンストラクタ内で何かオブジェクトを作ってメッセージングするやり方だと外側からsingerの存在に気付けない。

参考リンク

なぜオブジェクト指向は嫌われているのか? - カタチづくり
そのものズバリ
やっぱりOOPは整理術として利用すべきものなのか。

*1:外から受け取った変数の値を勝手に変更するのは好ましくないけれど、自分が持っている変数なら変更しても許されるという認識がある。だから副作用を持つ関数を使いたいのならたいていの場合オブジェクトのメソッドにする。