プログラムを複数のクラスに分割するのが良いのはなぜですか?[閉まっている]


62

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

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

このプロジェクトはJavaで行われ、記録のために私がプロジェクトに取り組んでいるのは私だけです。


1
ソフトウェアの各部分をよりシンプルにするために!infoq.com/presentations/Simple-Made-Easy-QCon-London-2012
TehShrike

49
あなたの本を読んだとき、それらは章とセクションに分かれていましたか?本がテキストを章に分割して物事を整理するように、プログラムをクラスに分割して物事を整理します。
リウォーク

12
ローマ人はかつて言った:分裂と帝国。
ジョルジオ

7
@Giorgio:または英語で、ラテン語はもはや使用されないため:Divide And Conquer
マチューM.

40
あなたが10年生であることを考慮して、すでにインテリジェントな質問を作成し、適切な回答に必要なすべての詳細、コンテキスト、あなたの相対的な経験、および質問をする理由の背景情報を提供することができました。あなたは私が現在働いている多くの人々よりもすでに資格があります
...-CaffGeek

回答:


71

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

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

もちろん、コードを小さな断片に分割することには、他にも数え切れないほどの利点があります。コードの保守性、テスト可能性、再利用性などです。一度に考える必要があります。


7
プログラミングの多くの概念/アイデア(OO原則、分散ソース管理、コーディング標準)は、チームで比較的大規模なプロジェクトに取り組む場合にのみ意味をなします。実際にそのようなプロジェクトに取り組んでいる理由を理解できます。
joshin4colours

40
それは注目に値しますだけで複数のクラスにプロジェクトを壊す/ファイルはあまり役に立ちません。本当に重要なのは、自己完結型のクラスを持つことです。そのため、1つのクラスを変更するために、プログラムについて他に何も知る必要はありません(そして、クラスを使用するために、実装方法を知る必要はありません)。これは、多くのクラスを含むコードが頻繁に表示されますが、実際のカプセル化がないためです。カプセル化は重要な部分です-カプセル化を実現する方法は詳細にすぎません。
モニカを復活させる

2
いくつかのキーワードは、「結合」または「分離」、「カプセル化」、「情報隠蔽」です。
マルクタニ

@BrendanLong、私は同意し、カプセル化はほとんど不可能であることも追加します。あなたはもちろんの別々のプログラムを書いている...しかし、お互いに依存していない多くの部分は、通常はありますが、唯一の依存関係を共有している場合を除き
ジョーので、

29

さて、最も単純な回答は「物事を整理するのに役立ちます」かもしれません。それ以外の場合は、ノートブックのセクションと比較してください。ここに「UIに関連するすべてのもの」と、ゲームプレイに関連するすべてのものをそこに置くと、単純に単純になります。

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

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


12

これはいい質問です!シンプルでよく尋ねられます。ええと...答えは、コンピューターサイエンスを勉強していて、おそらく深いオブジェクト指向を知らず、おそらく経験を積んでいない学生にとって、理解するのは簡単ではありません。

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

  • 読みやすさ:10000行のファイル内のコードを参照および記述することは、いくつかの小さな整理されたファイルよりもはるかに困難です。
  • 再利用性:単一のクラスを作成すると、コードの重複が発生する可能性があります。これは、より多くのコード行とおそらくより多くのバグを意味します(!)
  • テスト容易性:単一の機能のテストについてはどうですか?1つのクラスで1つのロジック機能を分離すると、作業が楽になります。
  • コードの保守性:バグを修正したり、複数のクラスを使用して機能を強化したりすることができます:素敵な小さなクラス。
  • プロジェクト構造:ooooohソースファイルが1つしかないプロジェクトがどれほどいものになるか想像できますか?

私はあなたの答えが好きで、いくつかの変更を加えたところです(まだピアレビューを取得する必要があります)。私が見逃している点は、SVN / GITのようなソフトウェアバージョン管理システムの変更を簡単に検出できることです。また、1つのプロジェクトで複数のプログラマーと並行して作業する方が簡単です。
マーティントーマ

懸念の分離、結束、分離は、OOPの規律よりもはるかに高い範囲にある概念です。命令的で論理的かつ機能的なプログラマーは皆、高い凝集力と低い結合を目指して努力しています。
サラ

8

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

今のところ、あなたが言ったように、あなたはあなたのプロジェクトで単独で働いています。ただし、将来的には、チーム設定で作業する必要がある場合があります。その間、作業を分割します(おそらくプロジェクトはかなり大きくなります)。その結果、いくつかの(実際には2つの主要な)異なるオプションがあります。1つのファイルの複数のコピーを作成し、ファイルの個別の「ピース」で作業してから、後でコピーアンドペーストで「結合」してから、パーツが連携できるように変更するか、これらの「ピース」をかなり分割することができますさまざまなクラスに簡単に参加して、それらのクラスをどのように作成するを話し合い、その知識を活用して進めてください。

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

頭の中でプログラムを保持する。ジョルジオからのリンク


1
+1:チームワークも重要です!たとえば、paulgraham.com / head.htmlと「同じコードを編集する複数の人がいない」というタイトルの段落を参照してください。
ジョルジオ

@Giorgio私はそれをざっと眺めただけですが、素晴らしいリソースのようです!一部の人々がコメントセクションを見ていない可能性があるため、これを回答に追加します。いつかもっと徹底的に読みましょう。
-Sephallia

これはリビジョン管理にも適用されます-別々のファイルで作業することで、競合やマージが少なくなります。
モニカを

7

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

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

Gerald Sussmanが言ったように、私たちのプログラムはまず人々が読むことができるように書かれ、次にコンピュータがそれを実行できるように書かれるべきです。(そして、「コンピュータープログラムの構造と解釈」をまだ読んでいない場合は、そうすべきです)


4

1つは複数のクラスを使用します。1つの大きなコードの場合は、より大きなものにたどり着くと、すべてを追跡する方法がなくなるためです。

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


3

オブジェクト指向プログラミングは、私がプログラミングで見た中で最高のアイデアです。しかし、それはすべての場合において最良のことではありません。その要点を見るには少しのプログラミング経験が必要であり、多くの人々はそうでないときにOOPを行うと主張しています。

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

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

Javaは、オブジェクト指向コードを書いている人のために特別に設計されています。しかし、最も強力なオブジェクト指向プログラムでも、構造化されたプログラミングを使用しているため、どの言語でもいつでも破壊できます。(私はオブジェクト指向をプレーンCで行いました。)したがって、JavaでSPなどを実行できます。クラスを忘れて、小さな管理可能なものに分解できる大きなメソッドに集中してください。SPを使用すると、コードを再利用したり、DRY(グーグル、ただし「自分を繰り返さない」という意味)の原則を利用したりすることができます。

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


0

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

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

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


0

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

クラスは、主にインスタンス化されるときに役立ちます。インスタンスが実際に作成されないクラスは、実際には単なる名前空間です。すべてのクラスをこのように使用すると、実際には、名前空間から名前空間に物事を移動することの利点は取るに足らないように見えるかもしれません。

しかし、これはクラスが輝く場所ではありません。Stringクラスについて考えてみましょうchar。配列といくつかの静的関数を使用して、すべて同じ機能を使用できます。この時点で、関数は少し余分な安全性と構文上の砂糖を提供します。string.length()代わりに書くことができlength(char_array)ます; それはそれほど大したことではありませんが、多くの人々はまだそれを好きです。さらに、誰かがあなたにを与えた場合String、それはStringコンストラクタで作成され、length関数で動作する必要があることを知っています-配列バージョンが文字を処理できない場合、そこに入れることを妨げる方法はありません。

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

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


0

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


0

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.