オブジェクト指向を学習中の初心者です。クラスとかインスタンスだとか、基本的な概念はそこそこには理解できてるつもりです。
そして、実装にあたってオブジェクト指向のエクササイズの9つのルールなるものを知り、それに関するサイトを色々と見てみました。
そこで、このルールに乗っ取るとたくさんのクラスが生まれ、クライアントから樹木状に伸びていくと思います。そうするとそのプロジェクトを初めて見る人にとっては把握するのがむしろ大変になりませんか?
扱いやすいようにしたとしても中身の細かい仕様を見たいときはあると思いますし、そうしたときにAを理解するにはB1とB2を理解する必要があって、B1にはC1とC2があって...というようでは扱いづらいのではないでしょうか?それとも、この手法は一般的には用いられていないものなのでしょうか?
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+4
こんにちは。
クラスを細かく分け、階層構造を作ると追い辛くなるのではという意見は良く理解できます。
しかし、オブジェクト指向におけるクラスの分割、階層化はそもそも「追う」ことを前提にしていません。
「抽象化とは何か」という話になってしまうのですが、クラス分けが実現しているのは「物事を行うために、知らなければならない範囲を小さくする」という概念です。
例えば、とある会社があるとします。この会社の「人事部」に「書類の作成」を依頼する際に、人事部の下に沢山の課があって、どの課にどんな社員が属しているかを考える必要はありません。
例えば、プログラムで「ファイルを読み込む」とき、どうやってファイルパス文字列からデータの格納位置を割り出しているのか知る必要はありません。
例えば、コンピュータを「使う」とき、CPU の中を電気がどのように通っているのかを知る必要はありません。
クラスの分割とは、「知らなければならないこと以外を分離する」という考えのもとで行われるのです。
「A を理解するには B1 と B2 が必要」というのは、言い換えると「A を使うのに B1 と B2 を知る必要はない」ということです。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
checkベストアンサー
+2
そこで、このルールに乗っ取るとたくさんのクラスが生まれ、クライアントから樹木状に伸びていくと思います。そうするとそのプロジェクトを初めて見る人にとっては把握するのがむしろ大変になりませんか?
そのために普通のプロジェクトではドキュメントを作成します。
ドキュメントのスコープや形式は色々ありますが、それらはシステムを理解する手助けをするものである、という共通の目標があります。
あなたのプロジェクトに今後入ってくるメンバーが把握するのが大変だ、と感じるようであれば、把握するために必要になるドキュメントを作成してください。
また、設計段階で抽象化のレベルをちゃんと意識して、適切な命名を行っていれば、ある程度構造を把握するための手助けにもなります。まず抽象度の高いものに着目し、具象的な命名となっているもの(つまり詳細な実装)をひとまず飛ばして読み進めることで、大まかな設計の意図はある程度汲み取れます。
質問文で提起している問題点はクラスの関係性についてのものだと思いますが、これを表現するためのUMLという記法もあります。関係をビジュアルとして表現できるため、ドキュメントとしてUMLを書いたり、コードからUMLを生成するツールを使うなどして、補助的に利用する場合もあります。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+2
「オブジェクト指向エクササイズ」の9のルールというのは、ToughtWorks アンソロジーという本の中で Jeff Bay 氏が紹介している方法ですが、
これはあくまでも、よいオブジェクト指向プログラミングができるようになるための「練習方法」であって、「思考停止してこれに従っていれば自動的に良いプログラムが出来上がる魔法の方法」ではありませんし、これらのルールはそのまま本番で適用することを意図したものではありません。
他の回答者さんも言っているように、「小さいクラスがふさわしいときは小さくするのが良い。そうでないときは小さいクラスにはしない」というのが実際のプログラマーが考えていることですが、これはトートロジーであって、「どういうときに小さいクラスにするのが良いのか?」「小さいクラスにはどういう利点があって、どういう欠点があるのか?」というのは、実際に自分で小さいクラスを実装してみなければ「体得」することはできません。
詳しいことが知りたれば、書籍を読んでください。ネットでアマチュアが書いた無料の記事や、Q&Aサイトで聞いただけではわからない知識というものは、あります。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
オブジェクト指向やらクラスやらと言っても、コードの構造がわかりやすいようにやってるモノなので、あなたの思うようにすればいいと思います。
まあ、言語の学習度合いや、経験などでそのわかりやすさってのは変わってきますんで、ベテランさんが提唱するわかりやすさってのは初心者のあなたは理解しづらいと思います。
まずはとにかくいろいろやってみて経験を積んでいくことでしょうね
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.21%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
LouiS0616
2020/11/15 11:03
『オブジェクト指向』タグがあるので、それをつけてみると良いかもです。
renge
2020/11/15 11:09
あ、本当ですね!英語名で検索してました。ありがとございました!
dodox86
2020/11/15 11:19
> そのプロジェクトを初めて見る人にとっては把握するのがむしろ大変になりませんか?
質問者さん自身が書かれているように、あくまで「初めて見る人」にとってであって、長らく付き合う人にとってはそうではない可能性の方が高いです。
renge
2020/11/15 11:25
同じプロジェクトとずっと付き合っていく場合はまさしくそうだと思いますが、他のプロジェクトに取り組んで、またその後前のプロジェクトに戻って機能を取り付けたいとなったとき、それぞれのクラスの仕様やどのオブジェクトがどのオブジェクトに作用しているかなどを覚えているかっていうと厳しいんじゃないでしょうか?不躾な質問でしたら申し訳ないです
hentaiman
2020/11/15 11:26
クラス分けしてプログラム作っている人達は分ける事が目的ではないですから、分けない方が良いと思えば分けないですよ。
その点について誤解なく質問されてますか?
renge
2020/11/15 11:30
確かに言われてみればそうですね。
では例えば、「全てのプリミティブ型と文字列型をラップする」というルールなどがありましたが、これもある程度無視しても良いんですかね?個人の裁量である程度柔軟に取り組んでいく形ですか?
dodox86
2020/11/15 11:32
不躾な質問とまでは思いませんが、質問の主旨としてはむしろ「オブジェクト指向で細かくクラス分けすることについて、いずれたくさんクラスが分かれてくると、そのプロジェクトを始めて見た、あるいはあまり理解が及んでいない人にとっては理解しづらくないでしょうか?」と言うアンケート的な質問なのでしょうか。つまり、自然とクラスが分かれてきてそのことによるメリットを享受するか否かは問題ではない、と。
Zuishin
2020/11/15 11:40
分類してわからなくなる規模なら、分類しないともっとわからないと思います。
dodox86
2020/11/15 11:43
ああ、hentaimanさんが既にコメントされていましたね。その通りだと私も思っていて、「オブジェクト指向プログラミングをするにはクラスを分けなければいけない」という発想からだと「なぜ分けなきゃいけないの?」の疑問につながります。そうではなく、自然と考えると対象によっては継承を含んだクラス階層になったり別のクラスに自然に分かれていきます。そこまで考える必要が無いならこだわる必要はないです。「オブジェクト指向のエクササイズの9つのルール」とやらを見てみましたが、どちらかというとコーディング標準に近い指針だと思います。
renge
2020/11/15 11:48
そういう意図ではなくて、自分のスタンスとしてまず複雑に枝分かれしたプロジェクトは作った本人であっても細部まで記憶することは難しいことではないのかというものがあって、分けてメソッドで記述されることによるコード単体の可読性の向上やテストが行いやすいなどのメリットがあるにしても扱いづらさがどうしても無視できないのではないかという質問です。ただ、y_waiwaiさんもおっしゃっていた通り、単純に慣れれば問題になくなるのであればこの質問は解決にさせていただこうかなという思いです
renge
2020/11/15 11:51
なるほど、分けることは自然に行われるものであって目的になってしまってはいけないんですね。納得しました
Zuishin
2020/11/15 12:02 編集
複雑に枝分かれし、多くのクラスが密接に依存しあって、すべて記憶しないと読めないのはただの失敗でしょう。適切にカプセル化できていないだけです。
Zuishin
2020/11/15 12:13
人に何か話すとき、とりとめなく時系列で話しながらあちこちに話が飛ぶようなやりかただとわかりにくくなります。
しかし話の流れと要点を整理し、まず主題が伝わってから細部を説明する方法をとるとわかりやすくなります。
ソースコードを読む際にも、実行される順にひたすらフローを追わなければならないものと、適切にモジュール化されているものでは読みやすさが違います。細かな部分をすべて隠蔽したまま概観をつかむことができれば、細部の実装を飛ばして読むことができます。
細かくクラス分けされていない場合、隠蔽された部分がそれだけ少ないということなので負担は増えます。
renge
2020/11/15 12:35
確かにそうですね。基本的な部分を失念していました。非常に納得しました。よろしければZuishinさんに回答をしてもらって、BAを差し上げて終了とさせてもらってもよろしいでしょうか?
dodox86さん、hentaimanさんの意見も非常に参考になりました。長い質問に丁寧に答えてくださって本当に助かりました。ありがとうございました。
できれば全員にBA差し上げたい所ですが、個人的に納得のいったZuishinさんにBA差し上げたいと思います。皆さん本当にお付き合いくださってありがとうございました
miyabi_takatsuk
2020/11/15 12:47
ここは質問修正依頼のコメントなので、BAにはできませんよ。
miyabi_takatsuk
2020/11/15 12:52
設計上、クラスにする必要があるからクラスで分けているだけで、
それ以外の何物でもないと思いますが。
クラスベースなら、クラス中心の設計にならざるを得ないのもありますし、
言語にもよるかと。
クラス分けすることが目的になってはいけないだけであって、
その設計が必要な要件だったからそうした、という基準が、プログラミングには必要だと思います。
Zuishin
2020/11/15 13:19
他にも有用な回答がつくと思うので、もう少し待ってみたらどうでしょうか。私のコメントは、クラス分けする利点のほんの一部でしかなく、実際にはテストやポリモーフィズムや依存性注入の観点からクラス分けを考えることが多いのではないかと思います。
renge
2020/11/15 13:25
miyabi_takatsukさん
確かにそうですね。hentaimanさんも仰っていたとおり、手段と目的を履き違えてしまったようです。貴重な意見ありがとうございました。
Zuishinさん
わかりました。もう少し寝かせてみようと思います。ありがとうございます
hentaiman
2020/11/15 13:47
> 「全てのプリミティブ型と文字列型をラップする」というルールなどがありましたが、
前提条件無しにそれだけ言われても判断つきませんが、問答無用でそれをルールとしているなら間抜けですね。たまたまそれが有効だった開発を経験をした、時の止まったおじいちゃんプログラマーが決めたルールとか?
> 手段と目的を履き違えてしまったようです。
とは言うものの、先人達の経験によって築き上げられたデザインパターンは基本的に有用なものなので、デザインパターンに沿って作る事を目的としても結果オーライな事がほとんどでしょう。
この辺は疑問を感じて質問するよりも手を動かして経験する方が良いかと。
renge
2020/11/15 17:40
なるほどです。とりあえず、既存のプロジェクトを細かいクラスにリファクタリングしていこうと思います。いざやってみるとどこまで区切ってクラスで取るかなど色々と難しいですが、自分のできる精一杯デザインパターンを踏襲して経験を積んでいこうと思います。