読者です 読者をやめる 読者になる 読者になる

長年にわたるオブジェクト指向議論に対する些末な反応

コメントに答えていきますよ。
>kmaebashi さん

オブジェクト指向がちゃんと定義されていないのは確かで、
だからこそ「長年にわたるオブジェクト指向議論」なんぞに
巻き込まれたくないと私は思っています。

ですが、いまのこれは既に「長年にわたるオブジェクト指向議論」なのではないでしょうか。
オブジェクト指向の○○といった時点でもう片足を突っ込んでいると思います。

私がやりたかったのは
オブジェクト指向の本質とは何か」という議論ではなく、
どの順番で説明すれば初心者にわかってもらえるか、でしか
ありません。

了解です。
ただ、自分はそこに違和感を感じたので書いています。

・何であれ、将来的に複数必要になる可能性は結構高い。

自分は高くないと考えてます。
普通に複数必要なもの、単数であるべきもの、があるだけだと想います。
比重の偏りはドメイン依存でしょうが……。

・最初から複数前提で書くことはさほど難しくない(複数生成
 できるものを、使う側で1個しか作らないのは自由)。

自分は難しいと考えています。
なんでも複数あれば良いというものではないからです。
複数のインスタンスを考えたときに余計な処理を踏まえなければならないので、
無駄だとも考えています。
やらなくていいのに複数前提で書くことは意味のないことです。
また、使う側に個数を任せるのは不安です。

・単一前提で考えたものを後になって複数にすることは
 結構面倒くさい。

まさに面倒なので、最初に考えます。
勿論、途中で変わることはあるでしょうが、それはそういうものだと思います。
作業ロスと言えばロスですが、実際殆どありません。
最初から全てを複数前提で書くよりましです。

すでにリンクを貼りましたが、Cでマルチプルインスタンス
オセロ盤を作成する例を最初のサンプルで挙げているのに、
なぜ「C(の関数)ではまるでマルチプルインスタンス
適切に働かないように書かれていたから」という解釈が
されるのか理解できません。

ですが、

Cプログラマにオセロゲームを作らせたら、 まず、盤面を以下のようなグローバル変数で管理しようとするのではないでしょうか。

と書かれていたからです。
いや、そんなことないですよね?

まとめを抜粋します。

  • Cでも、staticを使うことでカプセル化は実現できる。
  • カプセル化されたプログラムの塊を「モジュール」と呼ぶことにする。 Cで、staticにより作られたモジュールは、静的にひとつだけ存在する。
オブジェクト指向再入門/オセロを例に考える
  • Cなどの言語では、「関数」もしくはその集合体である「モジュール」に 仕事をさせていたが、オブジェクト指向言語では「オブジェクト」に仕事をさせる。
  • 「オブジェクト」と「関数」もしくは「モジュール」の違いは、 それが「複数存在しうるか」ということである。
  • 「関数」や「モジュール」は、「ひとつしかない」ので、 こういうものが何らかのデータを抱えると、そのデータは「ひとつしかない」 ことになる。
  • データが「ひとつしかない」ということは、いつ書き換えられても 不思議ではないと言うことであり、結局グローバル変数と同じ問題を抱え持つ。
オブジェクト指向再入門/オブジェクトに仕事をさせる、ということ

まとめだけ読めばそうだろ、と思うかもしれないですが、
中身を読んでもCではできない、と言っているように読み取りました。
「関数」や「モジュール」は1つしかない、「オブジェクト」がないCではマルチプルインスタンスができない、
と読めます。
差違としてあげられている「複数存在しうるか」という点でもそうです。

#「C(の関数)」と、わざわざ『の関数』が括弧で付けられて
# いる趣旨はよくわかりませんが。

Cという言語、及びCの関数、ないしはCのプログラマではインスタンスを用いたプログラミングができないように読み取れるからです。

ただし、もちろんOOPでは、通常は何でも複数生成を前提とした
設計にします。オセロ盤は、特に最初からネットワーク対戦とか
考えなくても普通クラスにしませんか?
Cでも、最初から構造体にするかもしれませんが、関連する関数
(メソッド)の第1引数でポインタを渡すようにしない限り、複数
使うことはできません。

クラスにするのは複数対応のためにではありません。
また、Cでも構造化するために構造体にします。
それは凝集度を高め、責任範囲を明確にするためです。
クラスにするのも構造体にするのも「凝集度を高めるため」です。
決して複数対応にするためではありません。

また、

複数作ることを考えないのなら「モジュール」でよいのでは?

とありますが、結合度を考えたときに、
いきなりモジュール化するのもためらわれるので、
構造化くらいだと自分は考えてます。
第一引数をポインタにしておき、
外部に公開するインターフェイスは引数でないものを出すようにすれば良いでしょう。
第一引数をポインタにするのは「この関数はこの構造に対して責任を持つのだ」ということを
実装部で明確にするためです。

board = new Board();

というプログラムを書かされたとき、Cプログラマ(の一部)は
なぜこんなことをしなければならないのか理解できないんですよ。
そこで、「ほら複数作りたくなったとき困るじゃん」と、私は
書いているわけです。

ですが、やっぱり自分は腑に落ちないのです。
Cプログラマだって複数のデータの扱いを長年Cでしてきました。
どうして理解できないんでしょう?
それは単に経験不足なんじゃないでしょうか、という想いを抱くのです。
少なくともmallocとfreeを使ってきたプログラマがそういう想いを抱くとは思えないのです。