- ベストアンサー
クラスの分割
画像処理のプログラムを書いているのですが、1つのクラスに必要な変数と関数をぶち込んだため、変数20~、関数20~、2000行くらいのクラスになっています。 このままでは見辛いので、クラスを処理ごとに分割して見易くしたいのですが、各関数でいくつか共通の変数を使用しているため上手く分割ができなくて困っています。 データのみのクラスを継承した子クラスを3つ作ってみたらインスタンスが3つできてしまい意味がありませんでした。 ↓の図に示すようなクラスを作りたいのですが、いくつか質問をさせてください 共通データクラス / | \ 子クラスA 子クラスB 子クラスC 1、変数20~、関数20~、2000行くらいのクラスは普通でしょうか?(分割する必要がありますか?) 2、↑の図はクラスの作り方として問題がありますか? 3、2で問題がない場合実現する方法として、仮想継承、関数に共通データのポインタを渡す以外に方法があるかどうか まだまだC++を勉強中で、便利な構造体程度にしか使えていませんが、どなたかご教授お願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
「メンテナンスが容易なプログラムは良いプログラム」と考えていますので、私なら一つのソースファイルが1000行を越えるようなソースコードは分割して然るべきだと思います。<クラスの有無に関係なく さて、クラスを分割する際の「視点」ですが、クラスは「責務」の単位で分割するのが基本です。C++のクラスを「便利な構造体」程度に見てらっしゃると言うことは、オブジェクト指向的な考え方に不慣れなせいで、とりあえず何でも詰めとけ的な設計になってしまったものと思います。 このように肥大化してしまったクラスに対する診断と処方について、 ○ リファクタリング http://www.objectclub.jp/technicaldoc/refactoring/u_s_r http://www.amazon.co.jp/gp/product/toc/4894712288/ref=dp_toc/250-7772931-5087426?ie=UTF8&n=465392 ○ Effective C++(スコット・メイヤーズ著) http://www.kaimei.org/note/book_out/eff_cpp1.html http://www.amazon.co.jp/gp/product/toc/4894714515/ref=dp_toc/250-7772931-5087426?ie=UTF8&n=465392 の二つが非常に有効です。前者は「外部に対する振る舞いを変えずに内部を洗練するための手法(のコレクション)」で、後者は「効率的な(C++を用いた)プログラムを設計するためのガイドライン集」です。 yami33さんが作ってらっしゃるプログラムの中身がわかりませんので、とりあえず手法/ガイドラインを紹介しました。 // GIFでもJPEGでもここに図を貼り付けられたら、クラス図を使って議論してみたい
その他の回答 (2)
- ddnp009
- ベストアンサー率25% (15/58)
分割しようとしているA, B, Cはもともと1つで、 それぞれから逐次使いたい値の群れとして『共通データ』がある。 と読み取れますけど合ってます? だったら図のようなクラス設計は誤り。それだと、 (Aのインスタンス + Aの親となったデータ群のインスタンス) (Bのインスタンス + Bの親となった...) (Cのインスタンス + Cの親となった...) みたいに、『共通データ』が各個分裂(独立?)してしまいます。 >1、変数20~、関数20~、2000行くらいのクラスは普通でしょうか?(分割する必要がありますか?) そもそもxxx行以上はダメ、みたいなものは無いでしょ? 関数の分割とはワケが違う。 ・・・とはいえ、でかいクラスは管理が大変、使うのも大変。 練りに練って、それが最小限のインターフェイスであるなら、それでいいんじゃ? >2、↑の図はクラスの作り方として問題がありますか? 先頭に挙げた仮定が合っていれば問題。 >3、2で問題がない場合実現する方法として、仮想継承、関数に共通データのポインタを渡す以外に方法があるかどうか 共通データの構造体(の唯一のインスタンス)へのポインタないし参照を A, B, C各クラスのprivateメンバにするしかないような気がする。
お礼
はい合ってます。 仰るとおり、そのまま共通データを継承させると、共通データのインスタンスが3つ別々にできてしまい意味がありませんでした。 自分なりに考えた結果3の質問のように仮想継承かポインタ渡しになりましたが、やはり無理に分割する必要は無さそうですね。 分割せずに最小限のインターフェースを練る方向で行ってみようと思います。 回答ありがとうございました。
- aris-wiz
- ベストアンサー率38% (96/252)
>クラスを処理ごとに分割して見易くしたい >各関数でいくつか共通の変数を使用しているため上手く分割ができなくて困っています。 クラスはそもそも、設計の段階で考えるもので、 分割する為に考えるものではないと思いますが。。。 既にあるクラスを分割するのなら、分離できるところと、 分離できないところを分けるしかないと思います。 きちっとした設計が出来ているなら、自然に機能ごとに 分かれるでしょう。 >1、変数20~、関数20~、2000行くらいのクラスは普通でしょうか?(分割する必要がありますか?) 動くのであれば、分割する必要は特に無いと思います。 クラスの中が長かろうと、短かろうと使用者は気にしないのが普通です。 >2、↑の図はクラスの作り方として問題がありますか? 何を実装しているクラスなのか不明なので、問題があるか 無いかわかりずらいですが、複数のインスタンスが 必要ないなら、その3つのクラスにデータクラスを わざわざ継承する必要は無いのではないでしょうか。。。? >3、2で問題がない場合実現する方法として、仮想継承、関数に >共通データのポインタを渡す以外に方法があるかどうか やることによりけりだと思います
お礼
動作的には問題ないのですが、他人がソースを見たときに見辛いのはまずいかなぁと思い分割したかったのですが無理にする必要はなさそうですね 回答ありがとうございます
お礼
回答ありがとうございます 個人でプログラムを組んでいるせいか、イマイチオブジェクト指向のメリットが理解できなくてまだまだC++を扱えていないのが現状です 参考HPにまだ全部に目を通していませんが、リファクタリングは非常に参考になりました おそらく求めていたことがここに書いてあると思います リファクタリングの書籍が図書館にあったので、現在読書中ですがJavaで書いてあるためちょっと時間がかかりそうです プログラムの中身はちょっと公開できないのですが、共通データが保持する複数の画像データを 関数1で処理→関数2で処理・・・ といったように順番に処理を行い、処理結果を画面に出力するといったようなプログラムです 他にもいろいろと処理がありますが、基本的に画像データに何らかの処理を行うだけなので、画像データの共有さえできれば分割できると思います ただ、動画像のリアルタイム処理なのでできるだけ負荷が軽いほうが望ましいです