質問

オブジェクト指向設計 (OOD) は、データとそのメソッドを組み合わせます。私の知る限り、これにより 2 つの素晴らしいことが達成されます。カプセル化 (つまり、データが何であるかは気にせず、必要な値を取得する方法だけを考慮します) とセマンティクス (データを名前と関連付け、そのメソッドは一貫して当初の意図どおりにデータを使用します) を提供します。

では、OOD の強みはどこにあるのでしょうか?対照的に、関数型プログラミングでは、豊かさは名詞ではなく動詞にあるため、カプセル化とセマンティクスの両方がデータ構造ではなくメソッドによって提供されます。

私は機能的には限界に位置するシステムを扱っており、OO のセマンティクスとカプセル化を常に切望しています。しかし、OO のカプセル化がオブジェクトの柔軟な拡張の障壁になる可能性があることはわかります。したがって、現時点では、セマンティクスがより大きな強みであると考えています。

それとも、カプセル化がすべての価値のあるコードの鍵なのでしょうか?

編集:ここで特に指しているのは、OO が提供するカプセル化のタイプです。 changeColor(door,blue) になる door.changeColor(blue).

役に立ちましたか?

解決

あなたは、のかなり狭い定義を使用しているように見える「カプセル化を。」私はあなたがすべきカプセル化を定義することを前提に、右だろう、「メソッドを使用してデータを組み合わせる?」

私が間違っている場合は、この記事の残りの部分を無視してください。

カプセル化が緩ん用語ではありません。実際には、それが国際標準化機構によって定義されています。オープン分散処理のISOの参照モデルは、 - 次の5つの概念を定義します:

エンティティ:関心の任意のコンクリートや抽象的なもの。

オブジェクト:エンティティのモデル。オブジェクトは、その状態によって、二重、その挙動を特徴としている。

(オブジェクトの)行動:。彼らは発生する可能性がありますときに制約のセットとアクションのコレクション

インタフェース:彼らが発生することときに、制約のセットと一緒に、そのオブジェクトの相互作用のサブセットで構成されたオブジェクトの挙動の抽象化

カプセル化:オブジェクトに含まれる情報は、オブジェクトのみでサポートされている界面での相互作用を介してアクセス可能なプロパティ

私たちはさらに自明の提案を行うことができますいくつかの情報は、これらのインタフェースを介してアクセス可能であるように、いくつかの情報が隠され、オブジェクト内にアクセスできなくする必要があります。プロパティこのような情報は展示パルナスは、モジュールが困難な決定と優れたコンピューティング論文のいずれかを参照、変更する可能性がある意思決定の両方を非表示にするように設計されるべきであると主張することによって定義される情報の隠蔽と呼ばれる

http://www.cs.umd.edu/クラス/ spring2003 / cmsc838p /デザイン/ criteria.pdfする

これは、それだけではなく、情報-隠されているデータであることに注意することが重要です:。それが困難または変更する可能性があるオブジェクトに関連付けられた行動のいくつかのサブセットです。

あなたの投稿で、あなたはOOでと関数型プログラミングでのカプセル化との違いは、データ管理に起因すると言っているように見えるが、少なくともISOとパルナスに応じて、データの管理は、カプセル化するための鍵ではありません。関数型プログラミングでのカプセル化はOOのものから任意の異なる場合が必要とする理由だから私は表示されません。

あなたが関数型プログラミングは、カプセル化を提供することをあなたのポストに、さらに、言うまでもなく「メソッドではなく、データ構造によって...。」これは、私が思うに、スケールのではなく、絶対の違いです。私は言葉、「オブジェクト」ではなく、「データ構造を、」使用している場合は(再び、私は誤解していた場合、私に知らせてください)、あなたは、オブジェクトとメソッドにより、関数型プログラミングのカプセル化によって、オブジェクト指向のカプセル化における重要性を見つけるように見えます。

しかし、上記のISOの定義によって、オブジェクトは、私がモデル化したいものです。このようなクラスは、パッケージ内に封入することができる限り、これらのクラスのいくつかはパッケージのインターフェイスに寄与するように(即ち、パブリックパッケージのクラス)といくつかの情報に隠されている(パッケージ内のプライベートクラス)。

同様に、メソッドは、クラス内にカプセル化されている - いくつかの方法は、公開鍵といくつかの民間います。あなたも、ノッチ下これを取ると、コードのMcCabianシーケンシャルシーケンスはメソッド内にカプセル化されていると言うことができます。それぞれは、カプセル化された領域内に封入されたノードのグラフを形成します。そして、すべてのこれらのグラフは、グラフスタックを形成します。したがって関数型プログラミングは、十分に機能/ファイルレベルでカプセル化されてもよいが、これはどちらかのOOの方法/クラスグラフとは異なる、及びオブジェクト指向のクラス/パッケージグラフから本質的に差がない全くありません。

変更:

また、パルナスは、上記の使用その言葉に注意してください。そのような将来的に困難な設計上の決定の変更などの懸念の潜在的なイベントを、情報隠蔽。あなたはOOの強さの嘘を尋ねます。よく、カプセル化は確かにOOの強さですが、問題はその後、となり、答えははっきりと明確性の一つである「カプセル化の強みはどこにあるのか?」:CHANGE管理。特に、カプセル化は、変化の最大の潜在的負担を軽減します。

、のコンセプト「潜在的な結合は、」ここに便利です。

「カップリング」自体は、コンピューティングの大きな紙の他に「別のモジュールからの接続によって確立された関連の強さの尺度」、のように定義される:

http://www.research.ibm.com/journal/ SJ / 382 / stevens.pdfする

、紙が言うように、言葉では決して良化、以降リップル 『の効果、変更の「モジュール間の最小限の接続も変更やエラーは、このように悲惨を、排除、システムの他の部分に伝播するに沿ってパスを最小化』別の1つのパート原因のエラー、他の場所で追加の変更が必要など、新たなエラーを生じさせる。」

ここで定義されるように、しかし、容易に持ち上げることができる2つの制限があります。まず、(紙がイントラモジュールを関連付けるために「結束」を、定義ない結合は、イントラモジュール接続を測定しない、これらのモジュール内の接続は、モジュール間の接続と同じくらい多くの、「リップル」の効果を生じさせることができます要素が、しかしこれは要素間の接続の観点で定義されていない(すなわち、ラベル又はアドレスへの参照)の結合が定義されたとともに)。そのモジュールが接続されているか、に第二に、任意のコンピュータプログラムの結合が、与えられます。パルナスが話すその電位変化を管理するためのカップリングの定義にほとんど余地がある。

プログラムのすべての要素のうち、成形可能な接続の最大可能数:

これらの両方の問題は、潜在的なカップリングの概念と、ある程度、解決されます。 Javaでは、例えば、パッケージ内のパッケージプライベートであるクラス(デフォルトアクセサ)がそれに形成された接続を持つことができない(すなわち、外部のクラスは反射にもかかわらず、それに依存することはできません)が、公共のクラスパッケージ内のことができますそれに依存しています。このpublicクラスは他のクラスは、現時点ではそれに依存していない場合でも、潜在的なカップリングに貢献する - ときの設計変更クラスは、将来的にはそれに依存するかもしれません。

カプセル化の強さを確認するには、負担の原則を考慮してください。負担の原則は、次の2つの形式をとります。

強いフォームは、エンティティのコレクションを変換する負担が変換エンティティの数の関数であると述べています。弱いフォームは、エンティティのコレクションを変換する最大の潜在的負担が変換エンティティの最大の潜在的数の関数であることを述べている。

任意のソフトウェアシステムを作成または変更の負担は(ここでは、オブジェクト指向のシステムを想定し、「クラス」、使用、およびクラス/パッケージレベルでのカプセル化を懸念しているに作成または変更されたクラスの数の関数である。我々同じように)関数型プログラミングの機能/ファイルレベルで自分自身を懸念している可能性があります。 (、「負担は、」現代のソフトウェア開発は、通常、コスト、または時間、あるいはその両方であることに注意してください。) 特に、変更されたクラスに依存するクラスが変更されたクラスに依存しないクラスよりも影響を受けてのより高い確率を持っています。

変更クラスが課すことができる最大の潜在的な負担は、それに依存するすべてのクラスの衝突である。

修飾されたクラスへの依存を低減すること、従って、その更新は他のクラスに影響を与える可能性を低減し、その結果、クラスが課すことができる最大の潜在的負担を軽減します。 (これは、「構造化設計、」紙の再声明より少しである。)

システム内のすべてのクラス間の依存関係の最大の潜在的な数を減らすことは、したがって、特定のクラスへの影響が他のクラスの更新の原因となる可能性を低減し、したがってすべての更新の最大の潜在的負担を軽減します。

DEPEの最大潜在的な数を減少させることによって、

カプセル化、ndenciesすべてのクラス間、従って負荷の原理の弱い形態を軽減します。これは、すべてのプログラムを構成する論理的手段としての潜在的結合を用いて、数学的に、このような主張を証明しようと、「カプセル化理論」で覆われている。

あなたが尋ねると、「?カプセル化は、すべての価値があるコードの鍵である」ことが

注、答えは確実でなければなりません:なし。すべての価値があるコードへの単一のキーがありません。カプセル化は、特定の状況では、それは、なるように、コードの品質を改善するための単なるツールである「価値がある。」

また、ことを書くはい、最も確かにすることができます「...カプセル化は、オブジェクトの柔軟な拡張への障壁になることができます。」:それは確かに困難であるか、または可能性のあるオブジェクトの設計上の決定を拡張に対する障壁になるように設計されて変更します。これは、しかし、悪いことではないと考えています。別のアプローチは、公開すべてのクラスを持ち、プログラムがその最大の潜在的結合を表す持っているだろう。その後負担の原則の弱いフォームは、更新がますます高価になるだろうと述べています。これらは、拡張への障壁が測定されるべきに対して費用のことである。

最後に、あなたはあなたの意見では、カプセル化とセマンティクス、およびそれとの間の興味深い比較を行い、OOの意味は、その大きな強みです。私はどちらか(私も良いミスターラムジーは、彼のコメントでそれに言及する前に存在し、そのような言葉を知りませんでした)何semanticistだんが、私はあなたが、の意味での「セマンティクス、」、「の意味、または意味推測します、横糸()メソッドは、犬と呼ばれるべきである。

との言葉の意味の解釈、」非常に基本的にはそのクラス

偉大な強さは、この意味論では確かにあります。

どのような私には好奇心旺盛であることは、あなたがカプセル化に対して意味を戦わし、勝者を探すということです。私はあなたが1を見つけることができます疑うます。

私の意見では、カプセル化をやる気二つの力があります:。セマンティックと論理的には、

セマンティックカプセル化は、単にカプセル化されたノード(一般的な用語を使用する)の意味に基づいてカプセル化を意味します。私は「ミネラル」は、2つのパッケージと呼ばれる1、「動物、」と呼ばれるものを持っているし、その後、次の3つのクラス犬、猫とヤギを与え、これらのクラスをパッケージそこに頼むことを教えてくれあれば与えられ、その後、カプセル化されなければなりません他の情報は、あなたがシステムのセマンティクスは三つのクラスが、ではなく、「動物、」パッケージ内に封入されていることを示唆していると主張することは完全に権利ないだろう「ミネラルを。」

他の動機は、カプセル化のために、しかし、ロジック、および上記潜在的結合の研究特に、です。カプセル化理論は、実際に潜在的結合を最小限にするために、クラスの数をカプセル化するために使用されるべきパッケージの数の方程式を提供します。

私にとっては、全体としてカプセル化は、このセマンティックと論理的なアプローチとの間にトレードオフがある:これはプログラム理解し、意味的に容易になる場合、私は私のプログラムの潜在的な結合が最小超えて上昇することができます。しかし、潜在的なカップリングの巨大な無駄なレベルは私のプログラムは関係なく、それがどのように意味的に明らかに再構成されていないする必要が警告されます。

(そして、良いミスターラムジーはまだ読んでいる場合は、あなたやあなたのsemanticist友人は私がここに使用している?より適切な用語を使用するのが良いでしょう、「セマンティクス、」相のためのよりよい言葉を与えることができます。 )

よろしく、 エドます。

他のヒント

カプセル化し、得られ抽象化は明らかにOOの主な強みです。名詞が動詞よりも高いセマンティック重要性を取るため、「モノ」の述語何「アクション」は、それらの上に呼び出すことができます。

最終的には、カプセル化のいくつかのレベルずに一貫性があり、保守性の形で複雑なシステムを設計想像するのは難しいます。

は、そのオブジェクトシステム、おそらくこれらのどちらを提供Lispのプログラマとして、私は言う:上記のいずれも

jwz:「擬似Smalltalkのオブジェクトモデルが失われ、(適切無外部オーバーライド・ルールによって制約)汎用関数が勝つこと」

私はあなたが考えるほど、あなたと他の人がここにリスト望ましい属性(カプセル化、モジュール化、など)はOOのように固有ではないと思います。彼らは、多くの場合、JavaスタイルのOOと一緒に提供さ、それのない純粋に帰結しています。

複雑性の分離 IMO はあらゆる設計の主な目標ですか:インターフェイスの背後にある機能をカプセル化する より簡単に使用できる 機能そのものよりも。

OO はそのためのさまざまなメカニズムを提供します。2 人の oyu は次のように述べています。

カプセル化 実際の実装から独立したカスタム サーフェスを設計できます。(言い換えれば、「シンプルであることは異なることを意味する」)。

セマンティクス 問題ドメインの要素を表すエンティティをモデル化できるため、理解しやすくなります。


一定の規模に達したプロジェクトは、複雑さを管理する練習になります。私は、長年にわたり、プログラミングは私たちが管理することを学んだ複雑さの限界に沿ってすくい取ってきたと主張したいと思います。

私はもう何年も関数型プログラミングに手を出していませんが、私の理解では、関数型プログラミングは、数学者が言う力強い、優雅、そして美しいという言葉の意味で最もよく説明できます。この文脈での「美しい」と「エレガント」は、複雑なシステムの真の構造または関連する構造について、それを驚くほど単純な観点から見て、見事な洞察を表現しようとします。複雑さを所与のものとして受け入れ、それを乗り越えようとします。

あなたが言及した柔軟性は、ニーズに応じてPOVを変更できる機能であると私は理解していますが、それはカプセル化に反します。ある立場では無意味な詳細であっても、別の立場では唯一の関連性があるかもしれません。

OO、OTOH は還元主義的なアプローチです。より高いレベルに行くことでPOVを変更します。「古い OO」では、POV の単一階層があり、このモデルでは、インターフェイスはさまざまな POV をモデル化する方法です。

言ってしまえば、○○の強みは「普通の人」に向いているということです。

何らかの形で モジュール性 スケーラブルな設計の鍵となります。人間には限界があるため、一度にあまりにも多くの情報を「理解」することはできません。そのため、問題を管理しやすいまとまりのある塊に細分化する必要があります。 理解 大規模なプロジェクトとその方法 仕事の割り当てを細分化する 多くの人が参加する大きなプロジェクト。

上記の目標を達成するために、大規模プロジェクトの最も効果的な「分割」/「パーティショニング」を選択するにはどうすればよいでしょうか?経験上、ここでは OO が大きな勝者であることがわかっています。また、OO をこの点で優れたものにする 2 つの重要な属性は次のとおりであることに多くの人が同意すると思います。

  • カプセル化された:各クラスは「シークレット」(実装に関して時間の経過とともに変更する必要がある可能性が高い一連の実装固有の前提条件)をカプセル化し、これらの前提条件にとらわれないインターフェイスを公開します。このようなカプセル化された抽象化を階層化することで、予想される変更に直面してコンポーネント/実装を簡単に交換できる堅牢な設計を構築することが可能になります。
  • 名詞中心:ほとんどのドメインでは、人間は最初にドメインの名詞/データについて考えてドメイン モデルを分解し、その後、各名詞に関連付けられている補助動詞を特定する方が優れているようです。

関数型プログラミング (FP) と OO について、私は次のように考えています。 ブログに書きました これについてですが、簡単に言うと、FP は実装技術に関するものであるのに対し、OO はプログラム構造と設計に関するものであるため、この 2 つは補完的であり、OO はスケールの「大規模」側でより支配的であり、FP はより支配的であると考えられます。 「小さい」端にあります。つまり、大規模なプロジェクトでは、高レベルの構造は OO クラス設計によって最もよく記述されますが、モジュール レベルの詳細 (実装、およびモジュールのインターフェイスの形状の詳細) の多くは FP によって最適に形成されます。影響を及ぼします。

オブジェクト指向設計の強みは、が遅延バインディングはデザインで発生したどのくらいに比例しています。これは、OOのケイ概念ではなく、Nygaardの概念です。 アラン・ケイはに書いた:

  

私にはOOPは、ローカルのみのメッセージングを意味し、   保持および保護と隠れ   状態 - プロセス、および極度の   すべての物事の遅延バインディング。かもね   Smalltalkの中やLISPで行います。そこ   で、おそらく他のシステムがあります   これは可能ですが、私は認識していませんよ   それらます。

文学の多くは、オブジェクト指向のC ++のアイデアに賛成して遅延バインディングを無視します。

のバックステップを取ると、より高いレベルからこれを見てみましょう。簡潔問題領域に対して、より自然な形で問題/解決策を発現する能力のいずれかの言語機能嘘の利点

OOPの力学を容易構造体と関数ポインタと無地Cで実装されています。あなたも、OOPのビットは、そのようにやって感じることができます。しかし、OOPのイディオムは、このような環境ではほぼ同じ迫っはありません。 OOPの実際の言語サポートがあります場合は、その後のパラダイムの表現が出てきて、言語がアイデアを実装方法があるかについて非常に実質的な影響を持っており、どのように「と言いました」。例えば、Lispでの閉鎖/ラムダを使用してコードの違い、のpython、ルビー、などを参照してください。

最後に、それはコンポーネントおよび基礎となる概念ではないのですが、むしろそれらがどのようにCでOOはそれが何であるか++作ること一緒に入れて使用しているので。

多型と一緒にカプセル化。 1つまたは複数のインターフェイスを実装する最もOOP言語のクラスの能力は、私のソフトウェアの開発に最も大きな影響を与えました。この機能は、私は正確に2つのオブジェクト間の相互作用を定義することができます。

唯一の相互作用を定義するが、年後、私は、コードのそのセクションに戻り、明確に何が起こっているかを見ることができるように、それを文書化していません。

この機能は、私は関数型言語上のOOP言語を使用して好む主な理由です。関数型言語で書かれた非常に強力なものの、私が発見したソフトウェアは、メンテナンスサイクルが数十年で測定されたときに維持するために痛みをすることにします。 (AutoCADで見つかったのAutoLISPソフトウェア)

私見、OOは、単に他のオブジェクトと対話するオブジェクトを意味します。 カプセル化は、単に概念を抽象化を意味します。だから、あなたが何かにソケットと.Connect()を作成します。それが接続されているどのように、あなたは本当に(基本的にはカプセル化の私の定義である)気にしません。

そして、純粋な関数型プログラミングは、通信するためにオブジェクトを使用することができます..しかし、これらのオブジェクトは不変である必要があります。だから、もう一度IMHO、FPは簡単にオブジェクト指向の概念を使用することができます。 Cのような命令型言語はまだ、例えば...使用すべきではありませんプライベートセクションで、各「クラス」のファイルをOOの概念を使用することができます。

あなたの質問は、レンガを分析することで家の利点を導き出したいように読みます。

セマンティックコンテキストとカプセル化を提供する機能を持つことは、OOのクラスの基本的な機能にすぎません。(レンガが特定の力に耐え、特定のスペースを主張することができます。)

例えを続けると、次のようになります。レンガを最大限に活用するには、レンガを組み合わせるだけです。まったく同じことがクラスとオブジェクトに当てはまります。

そこには デザインパターンが豊富です OOプログラミングに使用できます。それらのほとんどは、あなたが言及した「カプセル化」と「セマンティック」に依存しています。

これらのパターンのいくつかは、あなたの質問の3番目の段落に対する答えでさえあります。

  • 既存のクラスの動作を拡張したい場合は、派生クラスを作成できます。
  • 既存のオブジェクトの動作を拡張または変更したい場合は、次のことを検討してください。 デコレータパターン.

OOの真の力は多型ではなく、カプセル化です。カプセル化は、ある程度、達成可能であると関数型言語で使用されているが、関数型言語で実装されている場合多型は非常に厄介になります。

(のOOの力を理解するために4ののギャングによる "デザインパターン" をお読みください。)

@Phil、あなたは私が正しくあなたを理解していれば、前述の違いは、プログラムがデータ/メソッドを呼び出す方法との間にある:OOでは、最初のオブジェクト/インスタンスが存在し、その後、データは/オブジェクトのメソッドが呼び出されますオブジェクトを介して、機能的には、この方法は、直接呼び出されます。

しかし、機能的なプログラムの実装を見て、我々は(ファイルではなく、クラスに)データおよび方法が包まれていることがわかります。例えば、Cプログラムは、他のファイルによってアクセス可能な機能を宣言するヘッダファイルを有し、これらの宣言された関数を介してのみアクセス可能である場合、データはプライベートデータです。限り、プログラマが十分に慎重であるとして、オブジェクト指向におけるカプセル化のほとんどは、機能的なプログラムで実現することができます。 (でも継承が特定のポインタのトリックを使用して利用可能である。)

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