オブジェクト指向と関数型の違い

http://q.hatena.ne.jp/1227762281
サブルーチンや関数を使えばプログラムの「部品」を共通化できまが、オブジェクト指向を使えば「部品を組み込む枠」を共通化できます。
.
10種類のカンマ区切りテキストファイル(CSV)を出力するプログラムを作る、という例を考えると分かりやすいと思います。
1つ1つのCSV出力は、ファイルを開いてタイトル行を書き出し、データを取得し、ループしてデータを書き出すという手順で行われます。サブルーチンや関数を駆使して10種類のCSV出力処理を記述すると、各種類のCSVを出力するためには、この手順を10個分書くか、ファイルを開くなどの共通化できる手順を10回分ループしてタイトル行出力部分などをCSV種類ごとにswitchやif文で10分岐させる、というコードを書かなければなりません。
しかしオブジェクト指向ではCSV出力のBaseクラスを作成してそこに、ファイルを開いて[タイトル行を書き出し]、[データを取得]し、ループして[データを書き出す]という、CSV出力の枠となる手順を記述することで、枠となる手順を1個所にまとめることができます。(カギ括弧で囲んだ部分は各CSVごとに異なる処理が必要な個所。実際のコードではオーバーライド可能なメソッドとして記述します)
そのクラスを継承して各種類のCSVを出力するクラスを作成し、子クラス側ではCSVごとに異なる処理だけを記述すれば、CSV出力の共通手順を何度も書いたりswitchやifで不自然に処理を分岐させることなく10種類のCSV出力を行うコードを書くことができます。
このようにオブジェクト指向では、ある場所だけ各種類ごとに別の処理をして残りは同じ処理をしたい、というときに枠となる処理を1箇所にまとめるて共通化することができるのです。
.
上記のようなことは、関数をまるごと引数に渡せばサブルーチンや関数を使っても似たことができるのでは……と思われるかもしれません。しかし、各種類ごとに処理を変える必要がある場所が1,2箇所ではなく10個所以上もある場合はどうでしょう。やはり関数ポインタを引数に渡す方法だけでは無理が出てきます。
(それでも関数を引数に渡すという方法は、各種類ごとに処理を変える必要がある場所が1,2個所の場合には有効な方法で、実際にいろんな言語で活用されている方法ではあります。)
.
ちなみにクラスには他にも、変数や関数が見える範囲(スコープ)を制限してプログラマが把握しなくてはならない情報量を押さえるという効果もあります。この特徴も非常に重要ではありますが、これはC言語(not c++)のstatic, externでも出来ることなのでオブジェクト指向特有の特徴というわけではないと思います。
.
そして最後に、忘れてはならないことを1つ。
オブジェクト指向でコードを書くと、どうしても1つの処理が複数の場所に分散して、処理の内容を把握するためにプログラマが確認しなければならない範囲が増えます。そしてこれはプログラムの可読性を落とすマイナスの特徴です。
つまり、オブジェクト指向で書くと必ずある程度は可読性が落ちてしまうのです。ですから、オブジェクト指向で書くこと得られる可読性の向上やコードの拡張性が高くなるというメリットが、このデメリットを上回らない場合は、オブジェクト指向で書くとコードは無駄に読みにくくなってしまいます。
(オブジェクト指向の入門書などで載っているサンプルコードは、大抵はこの「オブジェクト指向で書くとコードが読みにくくなる」例になってしまっています。紙面の関係や理解しやすいコード量を考えると仕方ないのですが)
ありがちな例ですが、オブジェクト指向は薬に例えられます。正しく使えばプラスの効果をもたらしてくれますが、間違った使い方をすればそれは薬ではなく毒になってしまいます。
用法、用量を守って正しく使いましょう。


しまった!(回答の投稿に)でおくれた!


id:koujirou6218はてな人力検索質問への回答。