質問

ノート: :この質問は、aから編集された抜粋です ブログ投稿 私は数ヶ月前に書きました。にブログへのリンクを配置した後 コメント プログラマーについて。この投稿は私の最も人気があります。人々は「私はオブジェクト指向のプログラミングを取得しない」とタイプしているようです。 多くの. 。ここで、またはWordPressのコメントでお気軽にお答えしてください。

オブジェクト指向プログラミングとは何ですか?誰も私に満足のいく答えを与えてくれませんでした。私はあなたが彼の鼻で「オブジェクト」と「オブジェクト指向」と言っている人から良い定義を得ることができないと感じています。また、オブジェクト指向のプログラミング以外に何もしていない人から良い定義を得ることもありません。手続き型とオブジェクト指向のプログラミングの両方を理解している人は、オブジェクト指向のプログラムが実際に何をしているのかについて一貫したアイデアを与えてくれませんでした。

誰かが私にオブジェクト指向のプログラミングの利点のアイデアを教えてもらえますか?

役に立ちましたか?

解決

ソフトウェアは、コンピューター内に存在する機械または組立ラインと考えてください。一部の原材料とコンポーネントは機械に供給され、一連の手順に従って最終製品に処理します。この手順は、特定の順序で特定のパラメーター(時間、温度、距離など)に一部の原材料またはコンポーネントで特定の操作を実行するように設定されています。実行される操作の詳細が正しくない場合、またはマシンのセンサーが正しく較正されていない場合、または一部の原料またはコンポーネントが予想される品質基準内にない場合、操作の結果を変更し、製品が発生しない可能性があります予想通り。

このようなマシンは、その動作と許容可能な入力において非常に剛性があります。マシンは、設計者のインテリジェンスや現在の運用環境に疑問を呈していません。指示されている限り、引き続き手順に従います。原材料またはコンポーネントの変更が、後の操作で起こったことに劇的な影響を与える可能性がある場合でも、マシンはその手順を実行します。目的の結果を補償して生成するために、手順の変更が必要なものを確認するには、プロセスをレビューする必要があります。製品の設計または構成を変更するには、実行された操作またはその注文に大きな変更が必要になる場合があります。生産を担当する人々は、それらの間の望ましくない効果を減らすために、操作を可能な限り分離することの重要性をすぐに学びましたが、処理を受けるときに条件コンポーネントが存在する多くの仮定が行われています。最終製品がいくつかの異なる操作環境でユーザーの手に渡るまで検出されない可能性のある仮定。

それが手続き上のプログラミングのようなものです。

オブジェクト指向が提供するものは、コンポーネントの条件の仮定を削除する方法です。したがって、そのコンポーネントで実行される操作と、最終製品に統合する方法。言い換えれば、OOPは、特定のコンポーネントを処理し、それをより小さなマシンに提供するためのプロセスの詳細を取得するようなものです。プロセスを担当するより大きなマシンは、コンポーネント固有のマシンに、どの動作が行われると予想されるかを伝えますが、コンポーネント固有のマシンに手順の詳細を処理することができます。

非オブジェクト指向ソフトウェアよりもオブジェクト指向の利点については:

  • コンポーネント固有の動作 - 特定のコンポーネントを処理する方法の詳細を作成する小さなコンポーネント固有のマシンの責任により、コンポーネントが処理されるたびに、そのマシンは適切に行います。
  • 多型式 - コンポーネント固有のマシンは特定のコンポーネントに合わせて調整された操作を実行するため、異なるマシンに送信される同じメッセージが異なる動作をする可能性があります。
  • タイプ抽象化 - いくつかの異なるタイプのコンポーネントが、機械が行う操作に同じ語彙を使用することは、多くの場合理にかなっています。
  • 関心事の分離 - コンポーネント固有の詳細をマシンに残すことは、プロセスマシンがそのプロセスのより一般的で大きな懸念と、それを管理するために必要なデータのみを処理する必要があることを意味します。さらに、他のコンポーネントの変化の影響を受ける可能性は低くなります。
  • 適応性 - 専門分野に焦点を当てたコンポーネントは、使用するコンポーネントを変更したり、別のプロセスマシンで利用できるようにすることで、予期せぬ使用に適合させることができます。
  • コードの再利用 - 焦点が狭く、適応性が向上したコンポーネントは、より頻繁に使用することにより、開発コストを活用できます。

他のヒント

あなたのブログから、あなたは命令的なプログラミングと機能的プログラミングの両方に精通しているようであり、オブジェクト指向プログラミングに関与する基本的な概念に精通しているようですが、実際に「クリック」したことはありません。それを便利にします。私はその知識の観点から説明しようとし、それがあなたに役立つことを願っています。

そのコアでは、OOPは、問題ドメインをモデル化する「スマート」データ構造を作成することにより、命令型パラダイムを使用して高度な複雑さをより適切に管理する方法です。 (標準の手続き上の非オブジェクト指向)プログラムでは、変数とそれらをどうするかを知っているコードの2つの基本的なものがあります。このコードは、ユーザーや他のさまざまなソースから入力を受け、変数に保存し、その上で動作し、ユーザーまたは他のさまざまな場所に送信される出力データを生成します。

オブジェクト指向のプログラミングは、その基本的なパターンを取得し、小規模で繰り返すことにより、プログラムを簡素化する方法です。プログラムは、それをどうするかを知っているコードを備えたデータの大規模なコレクションであるように、各オブジェクトは、それをどうするかを知っているコードに結合した小さなデータです。

問題ドメインを小さな部分に分解し、できるだけ多くのデータがそれをどうするかを知っているコードに直接結び付けることを確認することにより、プロセス全体とサブについても推論するのがはるかに簡単になります。プロセスを構成する問題。

データをオブジェクトクラスにグループ化することにより、そのデータに関連するコードを集中化し、関連するコードを見つけやすく、デバッグすることができます。また、アクセス仕様の背後にあるデータをカプセル化し、メソッド(またはプロパティがそれらをサポートしている場合)を介してのみアクセスすることにより、データの破損または不変因子の違反の可能性を大幅に減らします。

また、継承と多型を使用することで、既存のクラスを再利用し、特定のニーズに合わせてカスタマイズすることができます。 (これは 決してすべきではないこと, 、あなたがそれを避けることができるなら。)あなたがあなたのベースオブジェクトを理解することを注意してください、またはあなたは終わることができます キラーカンガルー.

私にとって、これらはオブジェクト指向のプログラミングの基本原則です。複雑さの管理、コード集中化、およびオブジェクトクラスの作成、継承と多型の作成、およびカプセル化と使用による電力や制御を犠牲にすることなく安全性を高めることによる問題ドメインモデリングの改善プロパティ。これがあなたがなぜそんなに多くのプログラマーがそれが役立つと思うのかを理解するのに役立つことを願っています。

編集:コメントのジョエルの質問に応えて、

命令プログラムと根本的に異なる「オブジェクト指向のプログラム」に(あなたが概説したこれらの派手なてやしを除く)に何を含んでいるかを説明できますか?どうやって「ボールを転がして」

ここに少し免責事項。 「オブジェクト指向プログラム」の私のモデルは基本的にDelphiモデルであり、元Delphiチームメンバーによって作成されたため、C#/。ネットモデルに非常に似ています。私がここで言っていることは、他のOO言語では適用されないか、それほど適用されないかもしれません。

オブジェクト指向のプログラムは、すべてのロジックがオブジェクトの周りに構成されているプログラムです。もちろん、これはどこかでブートストラップする必要があります。あなたの典型的なDelphiプログラムには、呼ばれるSingletonオブジェクトを作成する初期化コードが含まれています Application. 。プログラムの開始時に、それは呼び出します Application.Initialize, 、次に電話 Application.CreateForm すべてのフォームに対して、最初からメモリにロードしたい場合、そして次に Application.Run, 画面上にメインフォームを表示し、インタラクティブなコンピュータープログラムのコアを形成する入力/イベントループを起動します。

OSからの着信イベントのアプリケーションとフォームは、オブジェクトのメソッド呼び出しに変換します。非常に一般的なことの1つは、イベントハンドラー、または.NETスピークの「代表者」の使用です。オブジェクトには、「xとyを実行するだけでなく、この特定のイベントハンドラーが割り当てられているかどうかを確認し、その場合は呼び出します」というメソッドがあります。イベントハンドラーは、メソッドポインター(メソッドへの参照とオブジェクトインスタンスへの参照を含む非常に単純な閉鎖)であり、オブジェクトの動作を拡張するために使用されます。たとえば、フォームにボタンオブジェクトがある場合、OnClickイベントハンドラーを添付して動作をカスタマイズします。これにより、ボタンがクリックされたときに他のオブジェクトがメソッドを実行します。

したがって、オブジェクト指向のプログラムでは、ほとんどの作業は、特定の責任を持つオブジェクトを定義し、メソッドポインターまたは別のオブジェクトのパブリックインターフェイスで定義されたメソッドを直接呼び出す1つのオブジェクトのいずれかを介してそれらをリンクすることによって行われます。 (そして今、私たちはカプセル化に戻ります。)これは、大学でOOPクラスを受講する前に戻ってきたという概念がなかったという考えです。

OOPは基本的に、私がそうであったように、あなたが途中でやろうとしていたかもしれない何かに与えられた名前にすぎないと思います。

私が赤ちゃんのプログラマーだったとき、フォルトランでさえ、サブルーチンへのポインターのようなものがありました。別のサブルーチンへの議論として、サブルーチンにポインターを渡すことができることは本当に便利です。

次に、本当に役立つ次のことは、データ構造のレコード内にサブルーチンへのポインターを保存することです。そうすれば、レコードはそれ自体で操作を行う方法を「知っている」と言うかもしれません。

彼らがそれをFortranに組み込んだかどうかはわかりませんが、Cとその子孫で簡単に行うことができます。

そのため、その下には、自分がやろうと誘惑されたかもしれないというシンプルで便利なアイデアであり、一部の人々がそれを怖い流行語でいっぱいの巨大な時流に変えたとしても、より最近の言語でやりやすいです。

さまざまな種類のOOシステムがあり、誰もが同意する定義を得るのは難しいです。 JavaのOOが一般的なLISPオブジェクトシステムにどのように似ているかを示しようとするのではなく、より慣習的なものから段階的に始めます。

散在するデータとして存在するオブジェクトがたくさんあるとします。たとえば、ポイントは、x、y、zアレイの要素です。ポイント自体を考慮するために、すべてのデータをcのようなものにまとめることは理にかなっています struct.

これで、データオブジェクトについては、データをすべてまとめています。ただし、手続きプログラムでは、コードが散在しています。幾何学的な形状を扱っているとします。形状を描く大きな機能があり、すべての形状について知る必要があります。領域を見つけるための大きな機能があり、別の関数があります。円のコードは複数の関数に散らばっており、別の種類の形状を追加するには、どの機能を変更するかを知る必要があります。オブジェクト指向のシステムでは、関数を同じ種類のものに収集します(class)データとして。したがって、すべてのサークルコードを見たい場合、それはにあります Circle 定義、そしてaを追加したい場合 Quartercircle 単にそのクラスを書くだけで、コードがあります。

これから利点の1つは、クラスの不変性、クラスの各メンバーについて真実であることを維持できることです。クラスの外側のコードをクラスデータメンバーを直接混乱させることを制限することにより、クラスデータを1か所で変更できるすべてのコードがあります。他の2つよりも長い)。これは、クラスのすべてのメンバーの一部のプロパティを頼りにすることができ、使用するたびにオブジェクトが正気かどうかを確認する必要はありません。

主な利点は、相続と多型に伴います。これらのさまざまな形状のすべてを、呼ばれるクラスのサブクラスとして定義することにより Shape, 、コードを操作することができます ShapeS、そしてそれは操作によって求められることを何でもするための形状のサブオブジェクトの仕事です。これは、新しい形状を追加したり、古い形状の動作を改良したりするときに、古いテスト済みのコードに触れる必要がないことを意味します。新しいコードを直接利用できる古いコードが自動的にあります。制御コードをすべての異なる可能な形状を認識させ、すべての異なる可能な形状を認識している関数を維持する必要があるだけでなく、単に形とその特性を扱うだけで、 Shape サブクラス。これにより、制御コードが簡素化されます。

ここにはいくつかの利点があります。クラスの不変性があるため、組み込みのタイプについて推論するのと同じように、大きなデータオブジェクトについて推論することができます。つまり、複雑な概念をより単純な概念に分割することがよくあります。サークルコードの大部分はに含まれているためです Circle, 、地域を増やしました。さまざまな場所でいくつかの異なる機能に散らばる円の概念はないため、ルーチン間の結合が少なくなり、同期することを心配する必要はありません。クラスは実際にはタイプであるため、既存のタイプシステムを利用して、クラスの互換性のない使用をキャッチできます。

OOにはさまざまな定義があります。はい。これらの多くを自分で見つけることができると確信しています。私は個人的に好きです REES RE:OO それらを理解する方法として。ポール・グラハムを引用して以来、あなたはすでにそれを読んだと思います。 (OOに興味のある方にはお勧めします。)ここでJavaの定義を多かれ少なかれ採用します{1,2,3,7,8,9}。

OOの有用性、特に私がそれにアプローチする方法の問題は、数千行のコードを使用してはるかに大きな答えに値します(一部は、単なる主張ではないように)。ただし、その仮説文書の概要を次に示します。

OOは、たとえば約数百行など、小規模でひどく役立つとは思いません。特に、機能的な影響を良くないOO言語は、あらゆる種類のコレクションや多くのデータ型を必要とするもので単純なことを成し遂げることを非常に苦痛にする傾向があります。これは、ほとんどのデザインパターンが作用する場所です。 彼らは基礎となる言語の低電力に関するバンドエイドです.

約1000行で、すべての操作とデータ構造、およびそれらの関連性を追跡することがより困難になり始めます。この時点で、データ構造と操作を明示的に整理し、モジュールの境界を描き、責任を定義し、それらに対してプログラムしようとしている間にそれらの定義を理解する便利な方法を持つ方法があります。

Java-Ish OOは、人気コンテストで優勝したこれらの問題の中間ソリューションです。それは、Javaの人々が不十分な言語によって作成された小規模な問題に適用されるのと同じメカニズムであるため、それは単なる組織化された方法よりも、すべての魔法の解決策のように見える傾向があります。機能的なプログラミングに精通している人は、ClosまたはHaskellのタイプクラスやC ++に閉じ込められたときのテンプレートメタプログラムなど、他のソリューションを好む傾向があります。 。

OOPは、オブジェクト間のオブジェクトと相互作用の観点から現実世界の概念をモデル化しようとします。人間として、私たちはオブジェクトの観点から世界を処理する傾向があります。世界には、特定のプロパティがあり、他のオブジェクトとの対話などを行うことができるオブジェクトがいっぱいです。 OOPでは、同様の用語で世界をモデル化できます。例えば、

  • 人はオブジェクトです。人は年齢や性別などのいくつかの特性を持っています。人は物事をすることができます:食べ、眠り、車を運転します。
  • 車はオブジェクトでもあります(ただし、タイプは異なりますが)。また、メーカー、モデル、年などのプロパティもあります。車は物事を行うことができます:動きます。

しかし、車はそれ自体で動くことができず、それを運転する人が必要です - オブジェクト間の相互作用。

OOP =データ構造 +メッセージパッシング +継承。これらはすべて、プログラミングモデルの論理的進化です。

OOPは(プログラマーによる)約90秒で理解できます(リンクについては私のプロファイルを参照してください)。概念は非常に簡単です。

それを適用する方法は別の問題です。ハンマーのスイング方法を知っているからといって、家を設計して建設する方法を知っているわけではありません。 ;-)

私はあなたが役立つかもしれないと少し前にブログ投稿を書きました: 手続き型とOOPが説明しました.

私が最初に理解した方法は次のとおりです。

オブジェクト指向プログラミングの前に、あなたは持っていました 構造化プログラミング. 。すべてがプロセスを中心にしています。あなたが自問しなければならなかった最初の質問は、」情報で何をしたいですか?".

オブジェクト指向プログラミングにより、データを中心としています。あなたが自問しなければならなかった最初の質問は、」魔女の情報私が扱う必要がありますか?"。これにより、抽象化が容易になります。

構造体を理解し、関数ポインターを理解し、関数ポインターを持つ構造を理解しているため、あなたの観点からは、オブジェクト指向プログラミングを単に「機能ポインターを持つ構造体を大量に使用して」と定義します。それはまだ伝統的な意味でプログラミングされています - それはすべてデータであり、データに作用するコードです。違いは、単にそのすべての情報がどのように定義されているか、そしてそれを定義する方法にどのようにアプローチするかです。

おそらく、単純化されているのは、従来のプログラミングは「いくつかのデータ構造を備えたコード」であり、オブジェクト指向プログラミングは「データ構造、いくつかのコードを含む」であることです。どちらにもデータ構造があり、両方ともコードがあります。したがって、オブジェクト指向プログラミングは、データの種類を前もって定義し、機能のセットを介してどのように通信するかについて契約を強制するという行為にすぎません。

ご覧のとおり、これはソリューションを実装するのにそれほど素晴らしい方法ではない、膨大なクラスのアプリケーションがあります。あなたはそのようなアプリケーションで構成されている世界に住んでいるようです。ブログ投稿では、「99本のビール」問題(「お気に入りのプログラミングショーケース」)の実装を検討することに言及しています。 99本のビールは確かにそのカテゴリの一部です。 99本のビールの実装を調べてオブジェクト指向のプログラミングを理解しようとすることは、ツリーハウスを見て高層建築を理解しようとすることに少し似ています。非常によく建てられた木の家でさえ、あなたにそれほど教えることしかできません。

TL; DR:OOプログラミングは、従来のプログラミングのようなものです。ただし、データ構造を前もって定義するためにより多くの努力を集中し、機能ポインターを介してそれらのデータ構造が相互に通信することを除きます。

ウィキペディアのページは、基本を得るのに良い場所だと思います。
http://en.wikipedia.org/wiki/object-oriented_programming

基本的に、IDEAは、OOPが改善しようとしていたものである手続き上のプログラミングが、モデル化されているプロセスに焦点を当てているということです。 OOPは、モデリングしている「もの」に焦点を当てているモデルに移行し、それらのプロセスとデータはそれらのものに含まれています。

そのため、例として、タスクリストを追跡するためのアプリケーションを設計していたとしましょう。手続きプログラミングでは、モデルのトップレベルエンティティは、タスクの作成、タスクの削除、タスク情報の変更など、OOPモデルで発生するプロセスになります。代わりに、タスクの作成に焦点を当て、そのタスクが責任を負うべきデータとプロセスについて考えてください。そして、タスクに関するメモを保持したい場合は、おそらくメモや何かなど、他のオブジェクトタスクが対話する必要があるものに焦点を当てます。

それが役立つことを願っています。それについて読んで、コードを見続けるだけで、突然「クリック」します。それが私の経験でした。

ライセンス: CC-BY-SA帰属
所属していません softwareengineering.stackexchange
scroll top