web-dev-qa-db-ja.com

プログラムを複数のクラスに分割するとよいのはなぜですか?

私はまだ高校生(10年生)で、まだ学校で実際のコンピュータコースを受講していません。私がこれまでにしてきたことはすべて、本を通してです。それらの本は私に継承などの概念を教えてくれましたが、プログラムを複数のクラスに分割することはどのように役立ちますか?本は私に言ったことはありません。

これは主に最近のプロジェクトのためです。これはアーケードビデオゲームです。一部の人々が言っ​​ているように、Flashゲームのようなものです(ただし Flashゲーム が何かはわかりません)。事は、それは唯一のクラスです。たった1つのクラスで完全に正常に動作します(ただし、たまに少し遅れる)。だから、私はそれを複数のクラスに分割することがどのように役立つかを尋ねているだけです。

このプロジェクトはJavaであり、記録のために私がそれに取り組んでいる唯一の人です。

62
kullalok

最も簡単な答えは、すべてを1つのクラスに入れると、新しいコードを書くときに一度にすべてについて心配する必要があるということです。これは小さなプロジェクトでは機能するかもしれませんが、巨大なアプリケーション(数十万行を話している)の場合、すぐに不可能に近くなります。

この問題を解決するには、機能の一部を独自のクラスに分割し、すべてのロジックをカプセル化します。そうすれば、クラスで作業するときに、コードで他に何が起こっているのかを考える必要がなくなります。その小さなコードに集中できます。これは効率的に動作するために非常に貴重ですが、巨大なアプリケーションに取り組んでいなければ感謝するのは困難です。

もちろん、コードをより小さな部分に分割することには他にも無数の利点があります。コードの保守性、テスト性、再利用性などですが、私にとって最大の利点は、コードの量を減らすことで大規模なプログラムを管理しやすくすることです。同時に考える必要があります。

71
Oleksi

さて、最も単純な応答は「それは物事を整理するのに役立つ」かもしれません。他に何もなければ、それをノートブックのセクションと比較するかもしれません-ここに「UIに関連するすべてのもの」とそこに「ゲームプレイに関連するすべてのもの」があれば、それは単純に単純です。

より洗練された答えは、作業を分割することは便利であるだけでなく、複雑さの管理にとって非常に重要であるということです(そして、「複雑さの管理」は、プログラミングに関してはほとんどゲームの名前です)。クラスまたは他のタイプのモジュールを使用すると、「個別の懸念」を解消できます。 「UIに関連するもの」を探す場所がわかっているだけでなく、UIに変更を加えたい場合は、1か所で行うことができ、その必要はありません。 「さて、フォントがComic Sansに設定されたのはonlyですか?」と心配します。また、変更を加えて、その変更の効果が適切な(小さな)スコープにのみ及ぶことを知ることができます。すべてが単一のクラスまたはモジュール内にある場合、基本的にすべてがグローバルであり、そのため事情を判断することが非常に困難になります。

ソフトウェアモジュールの一種としてのクラスの特定のケースでは、クラスに関連付けられている多くの動作もあり、オブジェクト指向パラダイムのほとんどの開発者は、関連するグループに関連付けられているクラスに関連付けられている意味のある名前を付けると非常に役立ちます一緒に機能します。したがって、おそらく実際にはUIクラスはなく、おそらくButtonクラスがあるでしょう。オブジェクト指向のクラス設計に関連する知識と手法はすべてあり、大規模なシステムを主流のプログラミングで編成する最も一般的な方法です。

29
Larry OBrien

これは良い質問です!シンプルでよく尋ねられます。ええと...コンピュータサイエンスを勉強している学生にとって、答えはそれほど簡単には理解できません。おそらくOOを知らないため、経験を積んでいない可能性があります。

したがって、私はシナリオを説明し、マルチクラスソフトウェアがモノリシックソフトウェア(1つのクラスのみで作成されたソフトウェア)よりも優れていることを想像させることで答えることができます。

  • 読みやすさ:10000行のファイル内のコードを参照して書き込むことは、いくつかの小さな整理されたファイルよりもはるかに困難です。
  • 再利用性:単一のクラスを作成する場合、 コードの重複 に陥る可能性があります。これは、より多くのコード行とおそらくより多くのバグ(!)
  • Testability:単一の機能のテストについてはどうですか? 1つのロジック機能を1つのクラスに分離すると、作業が楽になります。
  • コードの保守性:バグを修正したり、multiplieクラスを1つの場所(ニースの小さなクラス)で機能を拡張したりできます。
  • プロジェクトの構造:ooooohソースファイルが1つだけのプロジェクトがいかに醜いか想像できますか?
12
AngeloBad

ここには良い答えがたくさんあり、私はそれらに間違いなく同意しますが、言及する価値があるものがあると感じています。

現時点では、あなたが言ったように、あなたはあなたのプロジェクトで一人で働いています。ただし、将来的には、チームでの作業が必要になる場合があります。その間、作業を分割します(おそらくプロジェクトはかなり大きくなります)。結果として、いくつかのオプション(実際には2つmajor)が異なると思います。 1つのファイルの複数のコピーを作成し、ファイルの個別の「ピース」で作業してから、後でコピーアンドペーストで「結合」してから、パーツが連携して機能するように変更したり、それらの「ピース」を完全に分割したりできます。さまざまなクラスに簡単に参加し、それらのクラスを記述して方法について話し合い、その知識を使って作業を開始します。

個別の部品をすべて統合する作業はまだ必要ですが、保守がはるかに容易になります。 xファイルにはyコードが含まれており、それが変更が必要なコードです。これは、他の回答のほとんどが語っている組織のことです。

プログラムを頭に抱えている。ジョルジオからのリンク

8
Sephallia

実際、あなたがしたことは、再発明された手続き型プログラミングです。その方法でソフトウェアを書くことはかなり可能であり、コンパイラはおそらく気にしないでしょう。長年にわたり、これはコンピュータがより速くなり、ツールがよりよくなるまで物事が行われた方法です。

コードを異なる論理ユニット(クラス、モジュールなど)に分割した場合、言われるのは、コードの断片を理解しやすく、短くすることができるということです。それは後で維持することができます。私のモジュールの多くは、20行未満のコードです。特定の主題に関するすべてのコードが特定の場所にあることを知っています。また、他の誰かがプロジェクトに参加した場合は、物事を見つけるのがはるかに簡単になります。

ジェラルド・サスマンが言ったように、私たちのプログラムは最初に書いて、人々がそれを読むことができるようにし、次にコンピュータがそれを実行できるようにすべきです。 (「コンピュータプログラムの構造と解釈」をまだ読んでいない場合は、ぜひ読んでください)

7
Zachary K

1つは複数のクラスを使用します。なぜなら、より大きなものに入ると、それが1つの大きなコードの山であるときは、すべてを追跡することができないからです。

それを処理するには、分割して征服する必要があります。

4
Loren Pechtel

オブジェクト指向プログラミングは、プログラミングで今まで見た中で最も優れたアイデアの1つです。しかし、それがすべての場合に最適なわけではありません。それの要点を確認するには、プログラミングの経験が少し必要です。多くの人がそうしないと主張していますOOP 。

「構造化プログラミング」を調べることができれば、おそらくもっとすぐに役立つものが見つかります。 (必ずold構造化プログラミングについてお読みください。古い用語は新しい、より洗練された意味を持つことが多く、まだ特別なことは必要ありません。)これは、プログラムをサブルーチンに分解するというかなり単純な概念です。 、それをオブジェクトに分解するよりもはるかに簡単です。主なプログラムは、サブルーチン(Javaの「メソッド」)を呼び出して作業を行う短いルーチンであるという考え方です。各サブルーチンは、そのパラメータによって伝えられることだけを知っています。 (これらのパラメーターの1つはファイル名である可能性があるため、少し不正をすることができます。)したがって、サブルーチン/メソッドの見出しを見ると、それが何をするのかが簡単にわかり、メインプログラムのメソッドが何をするのかがわかります。 itが何をするかが一目でわかります。

次に、すべてのサブルーチンが同様に分解され、メソッド呼び出しのない数行のコードで問題が解決されます。いくつかのメソッドを呼び出すメインプログラム。それぞれがいくつかのメソッドを呼び出し、それぞれが...作業を実行する小さな単純なメソッドまで。このようにして、非常に大きなプログラム(または小さなプログラム)の任意の部分を見て、その機能をすばやく理解できます。

Javaは、オブジェクト指向のコードを書いている人のために特別に設計されています。しかし、最も強力なOOプログラムはいくつかの構造化プログラミングを使用しており、いつでも任意の言語を覆すことができます(私は単純なCでOOを行いました)。 JavaでSPなどを実行します。クラスを忘れて、小さくて扱いやすいものに分解できる大きなメソッドに焦点を当てます。SPを追加すると、コード、およびDRY(google it、ただし「自分を繰り返さないでください」という意味)の原則を使用。

うまくいけば、「クラス」を導入せずにコードを複数の部分に分割する理由と方法を説明しました。これらは優れたアイデアであり、ゲームにとっては単なるものであり、JavaはOOPにとって素晴らしい言語です。しかし、なぜ自分がやっていることをやっているのかを知った方がよいでしょう。 OOPは、自分にとって意味のあるものになるまでそのままにしておきます。

3
RalphChapin

利点の1つは再利用性です。プログラムは、基本的には一緒にグループ化された一連の命令です。これらの命令の一部は、他のプログラムにも適していることがわかります。

ジャンプゲームを作成するとします。後で大砲ゲームを作ることにしたとき、ジャンプゲームで使用した物理演算がここで便利であることがわかります。

だから、それをもう一度書いたり、悪いことにコピーして新しいプログラムに貼り付けたりするのではなく、クラスに作ります。したがって、次にゲームメカニクスに物理が必要な別のゲームを作成するときは、それを再利用できます。もちろんこれは単純化しすぎですが、私はそれが理にかなっていると思います。

0
gorengpisang

プログラムをクラスに分割することではなく、アプリケーションをモデル化する方法、つまりアプリケーションの一部を視覚化する方法についてです。物事を分割することは、複雑な物事をよりよく理解するために使用するメカニズムにすぎません。プログラミングだけではありません。多くのワイヤが絡み合って複雑な構造を形成し、各ワイヤがどこかに接続している回路基板(スパゲッティコード)を想像してみてください。接続を把握するには、各ワイヤを最後までたどる必要があります。逆に、グループ化され、機能ごとに色分けされたワイヤーを想像してみてください。物事を修正するのがずっと簡単になります。

長いプログラムから始めて、それをクラスに分割するのではないという考えです。ただし、最初にオブジェクト/クラスの観点からアプリケーションをモデル化し、次にそれらを接続してアプリケーションを構築します。

0
Vamsi

まず第一に、私はC++とPythonであり、Javaではないので、この一部は完全には適用されない可能性があることに注意してください。 Javaでクラスがどのように機能するかについて誤った仮定をした場合は、修正してください。

クラスは、インスタンス化されるときに主に役立ちます。インスタンスが作成されないクラスは、実際には名誉ある名前空間にすぎません。すべてのクラスをこのように使用する場合、実際には、名前空間から名前空間に物事を移動するメリットは取るに足らないものに見えるかもしれません。せいぜい、それぞれにプライベートデータがあり、それによって物事を少しカプセル化することで勝つでしょう。

しかし、これはクラスが輝く場所ではありません。 Stringクラスを検討してください。char配列といくつかの静的関数を使用して、すべて同じ機能を持つことができます。この時点で、関数はあなたに少し余分な安全と構文糖を与えます。 string.length()の代わりにlength(char_array)と書くことができます。それはそれほど大したことではありませんが、多くの人はまだそれを好きです。さらに、誰かがStringを渡した場合、それはStringコンストラクターで作成され、length関数で動作する必要があることを知っています。一部の文字を処理しないと、そこに配置できないようにする方法がありません。

しかし、それはまだそれではありません。重要な点は、クラスがデータとそれに作用する関数をバンドルし、両方を抽象化することです。メソッドvoid f(Builder b)があると、Builderを取得することがわかり、特定の動作をサポートすることが期待できます。ただし、データや実行されている関数については何も知りません。実際、fを記述してコンパイルするときに、両方の定義がまだ記述されていない場合があります。

したがって、最初に理解する必要があるのは、クラスを使用すると、データが壊れていないことを確認しながらデータを渡すのに便利であることです。 2番目のポイントは、オブジェクトが持つデータと機能(実装)はどちらもオブジェクトに関するものであり、型から単にわかるものではないということです。

0
Anton Golov

全体のアイデアは、 divide and conquer という名前の一般的なルールに基づいています。
このパラダイムは、ほぼすべての場所で使用できます。問題を小さな問題に分割し、これらの小さな、単純でよく知られた問題を解決します。
プログラムをクラスに分割することは、過去10年間に一般的になり始めた分割のタイプの1つです。このプログラミングパラダイムでは、いくつかのオブジェクトによって問題をモデル化し、これらのオブジェクト間でメッセージを送信することで問題の解決を試みます。
このアプローチの方が、理解、拡張、デバッグが容易であると言う人もいます。
ただし 一部の人 同意しない:)

0
Rsh