何の話か
クリーンコードにオブジェクト指向プログラミングと手続き型プログラミングについて興味深い記述があったのをメモしていたので、その供養として投稿します
注意事項
このメモは多態性とその活用方法がパッと浮かぶくらい/オープン・クローズド原則の重要性を理解していることを前提に書かれています
また、著者のボブおじさんはJavaをメインに扱っているそうですから、そのオブジェクト指向の捉え方もJavaのものに従っているようです
そのため、プロトタイプ指向/メッセージ指向畑の方の捉え方とは、少し毛色が異なるかもしれません
また、次項の定義はこのメモ用に切り取った解釈なので、わりかし乱暴です
オブジェクト指向自体の理解を深めたい場合、オブジェクト指向設計実践ガイドをお勧めします
定義
データ構造とそれを用いた関数をひとまてめにして扱うものをオブジェクト指向プログラミング
データ構造とそれを用いた関数を個別に扱うものを手続き型プログラミングとする
概要
オブジェクト指向プログラミングは、データ構造の追加には柔軟に対応できるが、関数の追加にはコストがかかる
手続き型プログラミングは、関数の追加には柔軟に対応できるが、データ構造の追加にはコストがかかる
この関係は表裏一体である
もう少し詳しく
実際のコードを鑑みると
手続き型プログラミングでは、さまざまなデータ構造を参照するさまざまな関数が存在する
ここにデータ構造を追加すると、既存の関数に、そのデータ構造を扱う処理を加える必要がありコストが嵩む
逆に、関数自体はそれぞれ独立しているため、既存のデータ構造に対する新しい関数の追加は容易に行える
対照的に
オブジェクト指向プログラミングは、多態を有効に用いればデータ構造の追加は新たな具象クラスの追加で済むので容易である(この辺の話がピンとこない方はStrategyパターンを参照ください)
逆に、関数を追加する場合、多態の元となるインターフェースそのものに新たな関数の定義を追加する必要があるため、その具象オブジェクト全てに変更を加えなくてはならずコストが嵩む
すなわち、どちらにもメリットデメリットがあり、しかもそれは表裏一体の関係にあると言える
とはいえ、複雑なシステムの開発においては新たな関数を追加するより新たなデータ構造を追加することの方が多い/有効なため、オブジェクト指向プログラミングに軍配が上がることが多い
どちらを用いるか問題領域に照らし合わせて適したものを選ぶのが熟練の開発者である
感想
手続き型は依存関係の矢印が
関数→データ構造
なので、関数はデータ構造に依存していますから、データ構造の変更/追加が関数に影響を与えると捉えられますね
また、オブジェクト指向は(ちょっと毛色が変わりますが)
具象→抽象
なので、関数(振る舞い)の追加は抽象に変更を加えることに他ならないため、具象に影響を与えると捉えられます
この辺の話がピンとこない方は、クリーンアーキテクチャを一読することをお勧めします
これを読んだ時は、オブジェクト指向と手続き型が表裏一体であるというのはすごい気付きだと興奮しました
ボブおじさんは、オブジェクト指向の神話に囚われることなく問題領域に対して適切な選択をするように説いていますから、気をつけないといけませんね