オブジェクト指向については全然詳しくない私の考えるオブジェクト指向の理解・・・という名の愚痴

ええ、きちんとオブジェクト指向を理解してる人には文句を言われそうですが・・・

○しっかりしたドキュメントのないオブジェクト指向は糞である。
なお、しっかりしたドキュメントとは、関数が提供する機能の概要と詳細、出来そうで提供出来ない機能の説明、引数として求められる値についての詳細(第二引数flagはtrueなら有効なデータを返す、falseなら無効なデータを返すとか)、簡単なサンプルコードを全ての関数について記述されたもので、かつ、クラス自体についても同等の説明が記述されたものである。
なぜならば、このレベルのドキュメントが無いと作成者以外のプログラマが当該のクラスを再利用することが出来ないからである。



オブジェクト指向における設計
1.ユーザ視点で必要な情報(画面など)、機能の割り出し
2.機能の抽象化
3.抽象化された機能を実現するために必要な機能を割り出す
4.2〜3をこれ以上細かくできないレベルの機能 or 既存のクラスで実現できる機能に分割できるまで繰り返す
(ここまでがトップダウン、ここからはボトムアップで考える)
5.4まで必要とされた機能について一番小さな機能から順に汎用化された関数やクラスをどう設計するか or 関数やクラスをどの再利用するか考える
6.1にたどり着くまで5.を繰り返す
7.全部終わったら設計完了で実装を進める


・・・とまあ、こんな感じで大丈夫か?


あるデータDBから取得しをCSVファイルに書き出すプログラムをトップダウンで考えると、1〜4で次のような機能が必要と分かる。

  • プログラム
    • DBからデータを持ってくる機能
      • DBに接続する機能
      • SQL文を生成する機能
      • DBにSQLを実行させる機能
      • DBから結果を取得する機能
      • DBから切断する機能
    • CSVファイルに書き出す機能
      • 与えられたデータをCSV形式に整える機能
      • ファイルを開く機能
      • ファイルに整形済みデータを書き込む機能
      • ファイルを閉じる機能


次に、これらの機能をどう汎用化して関数やクラスにするかをボトムアップで考える、5〜6で次のような機能が必要と分かる。


step1

  • DBに接続する機能
    • PDOクラスで実現できるのでそれを呼ぶコードを書けばよさげ
  • SQL文を生成する機能
    • 独自でコードを書く必要がある
  • DBにSQLを実行させる機能
    • PDOクラスで実現できるのでそれを呼ぶコードを書けばよさげ
  • DBから結果を取得する機能
    • PDOクラスで実現できるのでそれを呼ぶコードを書けばよさげ
  • DBから切断する機能
    • PDOクラスで実現できるのでそれを呼ぶコードを書けばよさげ
  • 与えられたデータをCSV形式に整える機能
    • 独自でコードを書く必要がある
  • ファイルを開く機能
    • 既存のfopen関数で実現できるのでそれを呼ぶコードを書けばよさげ
  • ファイルに整形済みデータを書き込む機能
    • 既存のfprintf関数で実現できるのでそれを呼ぶコードを書けばよさげ
  • ファイルを閉じる機能
    • 既存のfclose関数で実現できるのでそれを呼ぶコードを書けばよさげ


step2

  • DBからデータを持ってくる機能
    • step1のDB周りの各機能を順番に実行できるクラスをつくればよさげ
      • でも、SQL文を生成する機能は他のSQL文もかけるようにした方がより汎用的なので別のクラスとして定義して、引数でわたせるようにしよう
  • CSVファイルに書き出す機能
    • step1のCSVファイル周りの各機能を順番に実行できるクラスをつくればよさげ
      • でも、与えられたデータをCSV形式に整える機能は今回のデータ以外でも使えるように、いったん二次元の配列に入力を統一すればより汎用的につかえてあとで再利用できそう

step3

  • プログラム
    • step2で考えた、DBのクラスとSQL文の生成クラス、CSVのクラスをつなげばよさそうだ
      • あ、でもDBからのデータを二次元配列にしてからCSVのクラスに渡さないといけないので、DBからの結果を二次元配列に変換するクラスもひつようだな


・・・とまあ、こんな感じで大丈夫か?


○最近見たオブジェクト指向チックなダメコード
最初にオブジェクトとしてデータ構造をつくり、そのオブジェクトを常に第一引数として引き回し、各クラスの各関数内でそのオブジェクトを操作ようなプログラムを見た。
もちろん、返り値としてオブジェクトを返すならまだ分かるのだが、なぜか全て返り値はfalseとか訳がわからねぇ。
しかも、呼び元では返り値なんざ全然見てない。
たしかに、値渡しじゃなくて参照渡しなのでデータの書き換えは出来るんだけどなんか違うんでね?


オブジェクト指向って、各クラス毎にデータ的には普通は疎結合であるべきなんだと個人的には理解していたんだけれど、これじゃ超がつくほど密結合だよな・・・
仕様に変更があったら、全部コード書き直しになるんじゃねーのこれ?
・・・って感じで・・・orz


オブジェクト指向なコードはちょっと見たくねぇ・・・