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

続・関数はひとつしかないことが問題なのか?

お返事を戴いたのでレスでございます。

>id:kmaebashiさん
はじめまして、コメントありがとうございます。
ちと煽りっぽく書いてしまってお気に障られましたら申し訳ないです。

でも、関数の集合体である「モジュール」なら、(静的に)データを持つのはCでは珍しくないでしょう。

件のページでも挙げましたが、
・グラフィックを描画するCanvasについて、「ひとつしかない」想定の元、DrawLine(double x1, double y1, double x2, double y2)のような関数を作ってしまう(第1引数なし)。
・図形のコレクションを保持するShapeCollectionが「ひとつしかない」想定の元、RegisterShape(Shape shape);のような関数を作ってしまう(これも第1引数なし)。
という設計は、少なくともCでは、珍しくないのではないでしょうか。Cに限らず、HSPのLINE文なんかもそうですし。

モジュールに関してですが、
静的にデータを持つことが多いかというのはケースバイケースだと考えます。
「とある人がグラフィックを描画するCanvasを利用する際にまるでそれが単一であるかのように扱った、という件」については了解ですが、
実経験上に基づくと、
実際Cで組んだようなものもCanvasと呼べるものが単一であった事は殆どありません。

ハードウェアな話になりますが、
例えばNintendo DSGameboy Advanceといったものは物理的に「有数個」のCanvasのようなものを持っています。
これらは大きさも規格内において選択可能で、
(512x512や512x1024などといった固有サイズになります。)
メモリ的に重なっていることもあり、(重なっていないこともあります)

いかに関数を使って抽象化しようと、クラスにしようと、
物理的なハードウェア層を変更できる訳ではありません。
(仮想化する事はできますが、多くの場合、現実的ではないので利のないことです)

なので、モジュール化する際もその物理層にあわせた設計を心がけます。
どこに何を描くのか、は至極重要で「DrawLine関数で画面に線がでました」では多くの場合に困ります。
(描画順位、描画タイミングなど気にすべきところは色々ありますし)

ので、C経験者であろうと何であろうとCanvasが「ひとつしかない」という想定をするとしたら、
それは単に経験が足りないからではないでしょうか、
なんてことを思います。

Cで書こうとC++で書こうとJavaで書こうと、
ある一定以上の複雑なグラフィックを扱うようなアプリケーションを描こうとした場合、
画像が複数個ある、とかレイヤである、というような概念はまず無くてはならないものです。
寧ろ、これらは「オブジェクト指向」の知識とは全く関係がありません。

HSPは不勉強にして申し訳ないですが、
少し調べてみた結果、LINE命令は確かに唯一のデータに対して働くようですが、
これはちと厳しい設計だとは思います。
が、Cでこういう命令、Line(x1, x2, y1, y2)を作ってしまうことは、
「まず」ありません。(ありませんでした)

1日前のエントリでIsoparametricさんが書いておられるIsPadRelease(PORT1, PAD_CANCEL)だって、第1引数を付け忘れる人は多そうです(なぜかIsoparametricさんの例も、3つ中2つまでは第1引数ないですし)。結果として「複数のコントローラの問題」に陥るわけです。

kmaebashiさんが指摘されている
IsPadReleaseなども同様で、「物理的に」パッドの個数は確定します。
故に、可変個のインスタンスを作っても旨みは殆どありません。
(WindowsのようにUSBパッドが幾つも繋がるとしても、アプリ層で100個のパッドを扱う訳ではありませんよね)

自分の記述が足りないので申し訳ないですが、
ポートを指定する第一引数がないものはDSのようなパッドが単一であるものを想定しています。
ポートを指定する第一引数があるものは据え置きハードのようなパッドが複数であるものを想定しています。
4つしかポートがなければ基本的にデータは4つでしょう。
1つしかポートがなければ基本的にデータは1つでしょう。
これらのヘルパとして存在するクラスやモジュールならまた別でしょうけれど。

>C++だったらクラスにしてポートを隠蔽したりするかも。
とのことですので、最初からC++で考えていれば、問題を回避できたかもしれません。

ですが、
これをクラス化しても、
・ポート番号をメンバ変数で保持しておき、そのポートに対するアクセスだということを省略する
・キーバッファを別個に持つ
くらいで、特に「問題を」解決するわけではないのです。(自分で思いつく範囲ではですが)

キーバッファを複数持ちたい(入力の状態を複数個保持しておきたい)というときは、
Cでもバッファ構造を複数個持ち得て、適時渡すことになるでしょう。
C++でバッファがクラスで隠蔽されていれば楽でしょうが、
Cでやってできないことはありませんし、無理がある話でもありません。


しかし、これも「オブジェクト指向」とは関係がありません。(やはり設計上の問題です)
適切に設計されていれば、記述が増えるだけでCでも可能なわけです。


実質的に単一の存在であるものを複数の存在であるようにする旨みは「オブジェクト指向の本質ではない」と自分は考えます。
Cで複数個のものを扱いづらいか、というとそうでもないと思います。
クラスにするよりは面倒かもしれませんが、構造化されているべきものがされていればそれは多くの場合、適切です。


故に、Cでは単一でしかデータを扱えない、C++Javaなら複数個のインスタンスとしてデータを扱える、
これはオブジェクト指向の利点である、
ということは的を射ていないと個人的には考えます。


単一であるものも、有数個、例えば二つしかない、四つしかないというものでも、
オブジェクトとして考えたときに操作や理解が簡単になる、ということはあると思いますが、
それはオブジェクトに機能をまとめられるからであり、
決してCがモジュールに「複数個のものを扱えるように機能をまとめられない」ことを意味する訳ではないと考えるからです。