質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.91%

オブジェクト指向設計の学習

解決済

回答 4

投稿

  • 評価
  • クリップ 3
  • VIEW 1,843

BeatStar

score 1792

趣味でプログラミングをしている者です。

オブジェクト指向設計というのでしょうか? それを学びたいのですが、

何かわかりやすいサイトはありませんでしょうか?

わかりやすい・わかりにくい というのは人によって違うというのはわかっていますが、

私が自分で調べた範囲では ( 調べ方が悪いのか ) わかりにくいサイトがほとんどです。

JavaやC++ のような言語そのもの ではなくて、私が知りたいのは、

「オブジェクト指向の考え方を使ってどのように設計すべきか」です。

たとえばCの関数を使って C++で使える ファイルの入出力クラスを作るとします。

私が簡単に思いつくのが

  • ファイルパス : 文字列
  • FILEポインタ : FILE*
    + Write関数    : bool
    + Read関数     : bool

という感じです。

もうちょっとマシなものでも 入力用, 出力用 を分離するぐらいです。

ですが、Javaの場合は 「対象はどこか ( ファイル? コンソール? )」と 「処理」が分離されています。
( 入力用, 出力用 の分離は当たり前として。 )

私は Cを拡張して楽にしたような感覚 ( BetterC ) で C/C++を使っているので、

構造化というのでしょうか。その感覚でやってしまいます。

あとは、「株式会社アークシステム(infoARK)」のサイトでの

「関数とユーティリティクラスは禁止 - 株式会社アークシステム(infoARK)」

「privateメソッド禁止 - 株式会社アークシステム(infoARK)」には、

「関数はオブジェクト指向では不要」となっています。

メンバ関数という意味ではなく、メンバ変数 ( フィールド ) にアクセスしないメンバ関数のことのようです。

ですが、私からすると変に感じます。

たとえば、コンストラクタで

  • 引数を受け取ってメンバ変数 ( フィールド ) に設定

  • メンバオブジェクトであるvector ( listでもいいですが。 ) にデータを詰める

  • その他の前処理

を行うとします。

これをすべてコンストラクタに書けということなのでしょうか?

私の考えでは

引数 から メンバ変数
=> データ設定だけなので そのままコンストラクタ内で。

vectorにデータを詰める
=> 詰めるデータが多いので 関数化して void PushDataToVector() とします。

その他の前処理
=> 長くなるようなら関数化

となります。

ですが、上記サイトではダメとなっています。

こういう風に考え方が全然違う場合が多いので、

オブジェクト指向設計を説明しているサイトが欲しいのです。

オブジェクト指向の強みを生かしながらする方法が知りたいのですが、

「オブジェクト指向 設計」等で検索しても、

  • Amazon のような 書籍販売

or

  • 書籍の広告

or

  • 実際の業務である事

がほとんどです。

"実際の業務..." はまだいいですが、サンプルコードがそんなに載っていなかったりしてイメージしづらいものばかりです。

ファイルの入出力等ならそれでもいいかもしれませんが、DB ( MySQL etc. ) にアクセスして データを取得編集するクラス

とか言われてもイメージしづらい...

( MySQL 等は 名前はよく見るが 使ったことないし... )

どちらかと言えば その手の学校に通っている ( または 通って卒業した etc. ) 人か 上級者を対象としているのではないか

と...

プログラミングそのものはできる(?) のですが、オブジェクト指向で設計できているかどうかと言われたら、

まったくだと思います。

それなのに 上記のような説明されてもイメージができません。

私は最低でも

  • 箇条書きで必要要件等が記載されているような感じであること

  • サンプルとして そのソースコード が最低限 ( 呼び出し側からの使い方も含む ) が記載されていること

  • その他の条件等を文章で説明していること

で理解できる状態です。

特に サンプルがないとイメージができません...

たとえば、もし私が デザインパターンを説明するサイトを作るなら、

パターン名: TemplateMethodパターン


このパターンは 親クラス ( abstract, 通常クラス ) の メソッド ( メンバ関数 ) で

基本的な処理順番を記載し、継承させて実装させるパターンである。

[必要要件]

* TemplateMethodメンバ関数 ( 名前は変えてもいい ) を 親クラスで定義し、その中に処理を順番に書いていくこと

* 子クラスで定義するメンバ関数を (純粋)仮想関数 として親クラスで保持すること


[適用する場面]

* インターフェースのような親クラス ( abstract, 通常クラス ) として使用し、流れは一緒だが、
実際に行う処理が違う場合


例:
[ C++ ]

class CParentTest{
      public:
                 CParentTest(){}
                 virtual ~CParentTest(){}


                 // 与えられた数値から文字列を生成する。
                 // TemplateMethodパターン。
                 // このように親クラスで使用するメンバ関数内で流れを書いておけば
                 // 親クラスのように動かすことができる。
                 std::string TemplateMethod( int a, int b ){

                             int c = calc( a, b );

                             int d = check( c );

                             return name( d );
                 }

      protected:
                 // 以降は継承した子クラスで定義するメンバ関数
                 virtual int        calc( int a, int b ) = 0;
                 virtual int        check( int n ) = 0;
                 virtual std:string name( int n ) = 0; 

};

class CChildTest{
      public:

      private:

               // 親クラスで純粋仮想だった関数の定義

               int        calc( int a, int b ){
                          int n;

                           // 何らかの計算

               return n;
               }

               int        check( int n ){
                          int n;

                           if( n == 0 ){
                                  // 略
                           }else{
                                  // 略
                           }
               return n;
               }

               std::string name( int n ){
                          string str;

                           // 何らかの計算

               return str;
               }
};


int main( void ){

    // FactoryMethodパターンのように
    // 親クラス型として 生成。ただし、中身は 子クラス。
    CParentTest* Test = new CChildTest();

    cout << Test->TemplateMethod( 1, 2 ) << endl;

    delete Test;

return 0;
}

のような感じの方がイメージしやすいのです。

( サンプルでは 「何らかの処理」ってありますが、例の例なので省いています。実際にはちゃんとした式かなんかが書いてあるとします。 )

その手の学校に行けば学べると思いますが、私は趣味で独学でやっているのでその方法は無理です。

書籍を買う方法もありますが、できれば無料でできたらなぁと。

言語は できれば C/C++ ( C++ ) がいいですが、 Javaでも OK です。

宜しくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+3

こんにちは。

「オブジェクト指向プログラミング入門」で検索してみたら、それっぽい解説サイトがいくつかでてきました。2~3みてみたのですが、なんか違う感じがします。
どれも目的を見失っているからだと思います。
何のために「オブジェクト指向でプログラムを記述するのか?」の視点が丸っと抜けて「オブジェクト指向のプログラムってこんな形ですよ」という形だけ解説が多いように感じました。(ざっとしか読んでないので、実は書いてあるページもあるかもしれません。)

人類がプログラム開発で苦しんでいることは、生産性、メンテナンス性、信頼性です。(人材不足などもありますが、それらは教育や資金の話なので外します。)
これらは「如何に短期間で使えるものを開発するか」、「バグ修正や機能の追加/変更を継続してできるのか」、「必要な時に正しい出力をできるか(落ちたり間違った答えを出したりしないか)」、です。

私はオブジェクト指向プログラミングは生産性やメンテナンス性を改善するためにたいへん有効な開発手法と思います。その結果、信頼性も向上します。
でも、ごめんなさい。それは何故なのか具体的に説明して下さいと言われると詰まってしまいます。言語化できていない(=ちゃんと分かってない)です。

そこで、「オブジェクト指向プログラミング 生産性」で検索してみたところ、1つ本質に迫っているように感じるページがありました。構造化プログラミングからオブジェクト指向への進化です。

このような解説を参考にしつつ、オブジェクト指向プログラミングの入門サイトで解説されている構造が、生産性やメンテナンス性、信頼性を上げるのにどのように役に立つのか考えて把握していけば、その応用方法も自然に分かってくるのではないかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

ご自身もおっしゃられているように、デザインパターンをベースにした方が、どのような場合に利用できるものかをイメージできて良いかと思います。

そういう意味では、個人的に、結城さんが執筆した「Java言語で学ぶデザインパターン入門」あたりが参考になりました。Java言語ではありますが、言語が特にわからなくても、なんとなくイメージできたと思います。かなり前に読んだので、今となってはあまり詳細に覚えていませんが。。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

0

すごく大雑把に言うと、データを渡してデータを戻すのは関数指向。
データはオブジェクトが保持し、データの操作はメソッドで行うというのがオブジェクト指向。

僕もデザインパターンを学ぶのが手っ取り早いと思いますね。
デザインパターンはオブジェクト指向のテクニック集だと思うので。

tomohiro_obaraさんが紹介している本は僕も読みました。
説明に使われている言語はJavaです。
当時からこの本はすごく評価が高くて、その流れで読んでみたのですが、
特別分かりやすいなぁとか、説明に工夫されてるなぁとかは思いませんでした。
けっこう気合いを入れないと読めない本でしたね。
ただCD-ROMがついていて、そこに本で使われているコードが入っているので、
それを動かしながら僕は進めました。
「なるほど」と思うことが多くありました。

できれば無料で学びたいとのことですが、本は1冊読んだ方がいいと思います。
デザインパターンには、独学では中々思いつかない領域の思想があります。
センスがある人であれば、たどりついちゃうのかもしれないですけど。

あとは、オープンソースのSDKなどを読んだりするのもいいですね。
例えば、Javaのioパッケージは、デコレーターパターンが使われていて、とても汎用的にできています。

new BufferedReader(new InputStreamReader(System.in))


みたいなやつですね。
使いづらい、分かりづらいと悪評の多いパッケージですが、
設計思想としてはとても良く出来ていると思いますし、僕は好きです。
ただ、よく使われる組み合わせは、組み合わせた状態のものを
専用クラスで最初から用意してくれくれよな。。とは思います。
java7からはFilesが用意されて、ファイル操作はけっこう楽になりました。

「関数とユーティリティクラスは禁止」「関数はオブジェクト指向では不要」は
軽く見てみましたが、色々考え方があるんですねぇ。。。僕は同意しかねますが。

状態を持つ必要がなく、繰り返し何度も利用したい処理ってのは絶対にありますからね。
状態とは、ようはインスタンス変数のことですね。

ユーティリティクラスも作りますし、privateなメソッドも使います。
ただ、ユーティリティクラスはオブジェクト指向に反する存在だと理解はしておくべきです。

そもそもこのサイトは、関数は作っちゃダメとかコテコテのオブジェクト指向の説明をしているわりに、
説明に使っている言語がJavaの時点で何とも言えない感じはします。

Javaは純粋オブジェクト指向言語ではないので。
やっかいなプリミティブ型がいますし、= や + などは演算子であってメソッドではないですからね。
配列も「配列オブジェクト」ではないですし。
だから配列操作をマシにするために、java.util.Arrays のようなユーティリティクラスが
標準で用意されているのでしょう。

賛否両論ありそうですが、なんなら最初は全てprivateなスコープで作っていき、
必要なものを後からpublicにしていけば、カプセル化されたそれっぽいものができると思いますよ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

私は書籍を買うことをおすすめします。

手早く学びたい様子が伺えますが、オブジェクト指向は考え方も含めて大事なので
腰を落ち着けて学ぶのがよいから、WEBよりも書籍が向いています。

好みがあるようなので、大きめの書店で立ち読みをして選ぶと良いと思います。

オブジェクト指向のやり方を言語によって癖があるので、あまり厳密に捉えずどこらへんが良いのかを感じ取るようにしましょう。(継承の仕組みとか、関数渡しが出来るとかそういう言語仕様の違いが設計に影響します。)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る