OOPは自然ではないので難しいですか?


86

多くの場合、OOPは自然に人々が世界について考える方法に対応していると聞きます。しかし、私はこの声明に強く反対します:私たち(または少なくとも私は)遭遇するものの間の関係の観点から世界を概念化しますが、OOPの焦点は個々のクラスとその階層を設計することです。

日常生活では、OOPの無関係なクラスのインスタンスになるはずのオブジェクト間に、ほとんどの関係とアクションが存在することに注意してください。このような関係の例は次のとおりです。「私の画面はテーブルの上にあります」。「私(人間)は椅子に座っています」; 「車が道路にあります」; 「キーボードで入力しています」。「コーヒーマシンは水を沸かす」、「テキストはターミナルウィンドウに表示される」。

動詞が2つのオブジェクトに作用して何らかの結果/アクションを生成するアクション(関係)である2価(たとえば、「私はあなたに花を贈った」など)の動詞の観点で考えます。フォーカスがアクションであり、2つ(または3つ)の文法上の】オブジェクトが等しく重要です。

それとは対照的に、最初に1つのオブジェクト(名詞)を見つけて、別のオブジェクトに対して何らかのアクションを実行するように指示する必要があるOOPとは対照的です。考え方は、名詞で動作するアクション/動詞から名詞で動作する名詞にシフトします。これは、すべてが受動的または再帰的な音声で言われているようです。たとえば、「テキストはターミナルウィンドウで表示されています」。または、「テキストは端末ウィンドウに表示されます」。

焦点が名詞にシフトされるだけでなく、名詞の1つ(文法主題と呼びましょう)には、他の名詞(文法オブジェクト)よりも高い「重要性」が与えられます。したがって、terminalWindow.show(someText)とsomeText.show(terminalWindow)のどちらを言うかを決定する必要があります。しかし、実際にshow(terminalWindow、someText)を意味するのに、操作に影響を与えることなく、このような些細な決定を人々に負わせるのはなぜですか?[結果は操作上重要ではありません。どちらの場合もテキストはターミナルウィンドウに表示されますが、クラス階層の設計において非常に深刻な場合があり、「間違った」選択は複雑で保守が難しいコードになります。

したがって、OOP(クラスベース、シングルディスパッチ)を行う主流の方法は難しく、それは非自然的であり、人間の世界に対する考え方に対応していないためです。CLOSの汎用メソッドは私の考え方に近いものですが、残念ながら、これは一般的なアプローチではありません。

これらの問題を考えると、OOPを行う現在の主流の方法が非常に一般的になったのはどうしてですか。そして、もしあれば、それを退位させるために何ができるでしょうか?


OOPは「プログラミング」用であり、コンパイラーが楽しめるように作られています。現実世界をモデル化する方法ではありません。OOPを教える際、動物クラスや長方形クラスなどの実世界の例を使用するのが一般的ですが、これらは概念を簡素化するための単なる例です。残念ながら、プログラミング言語とパラダイムは、非進化的かつ非科学的な方法で「発生」します。いくつかの例外を除いて、言語設計プロセスは通常、少数の人々の最良の推測の子です!
-NoChance

3
「OOPの焦点は、個々のクラスとその階層を設計することです」という主張には同意しません。maybieはOOPの特定の実装の焦点ですが、たとえば、動的なOOP言語には通常、大きな階層やクラスさえもありません。さて、OOPの定義は将来変更される可能性があります。Object1
Azder

1
OOPは、システム内のオブジェクトを識別し、それらのオブジェクトに基づいてクラスを構築しています。その逆ではありません。これが、「OOPの焦点が個々のクラスとその階層を設計すること」にも同意しない理由です。
ラドゥムゼア


1
これは非常に主観的な質問であり、OOPと「現実の世界」とは何か、人々が問題についてどう考えるかについての奇妙な仮定に満ちていると思います。そして最後に、「それを廃止するために何ができるのでしょうか?」これは、OPがこれについて非常に強い意見を持っていることを示しています。あなたがプログラミングのパラダイムについて「宗教的」であれば、答えは必要ないと思います...あなたはすでにあなたが聞きたいことを知っています。それが最初に尋ねられたとき、私はこの質問については知っていたなら、私はおそらく...それを閉じるために投票したい
サイモン・レーマンを

回答:


97

OOPはいくつかの問題で不自然です。手続き的です。機能的です。OOPには2つの問題があり、本当に難しいように思えます。

  1. 一部の人々は、それがプログラミングの唯一の方法であり、他のすべてのパラダイムが間違っているように振る舞います。私見では誰もがマルチパラダイム言語を使用し、現在取り組んでいるサブ問題に最適なパラダイムを選択する必要があります。コードの一部にはオブジェクト指向スタイルがあります。一部は機能します。いくつかはまっすぐな手続き型です。経験を積むと、どのパラダイムが何に最適かが明らかになります。

    a。通常、オブジェクト指向は、操作対象の状態に強く結び付けられた動作があり、状態の正確な性質が実装の詳細である場合に最適ですが、その存在を簡単に抽象化することはできません。例:コレクションクラス。

    b。手続き型は、特定のデータと強く結びついていない一連の動作がある場合に最適です。たとえば、おそらくプリミティブデータ型で動作します。ここでは、動作とデータを別個のエンティティとして考えるのが最も簡単です。例:数値コード。

    c。関数型は、宣言的に簡単に記述できるものがあり、状態の存在が簡単に抽象化できる実装の詳細である場合に最適です。例:Map / Reduce parallelism。

  2. OOPは一般に、十分にカプセル化されたコードを保持することが本当に必要な大規模プロジェクトでその有用性を示します。これは、初心者プロジェクトではあまり起こりません。


4
質問の重要なポイントは、OOPが自然かどうかではなく、OOPへの主流のアプローチが最も自然なOOPアプローチかどうかだと思います。(とにかく良い答え。)
ジョルジオ

11
「OOPは一般に、十分にカプセル化されたコードが必要な大規模プロジェクトで有用性を示します。」:ただし、命令型、機能型、...プログラミング言語にも優れたモジュールコンセプトがあるため、これはOOPの特定のプロパティではありません。
ジョルジオ

2
OOPは、実際には手続き型/機能とは異なる軸にあります。操作を記述する方法ではなく、コードを編成およびカプセル化する方法に取り組んでいます。(あなたは常に OOPを実行パラダイムとパートナーにしています。はい、OOP +関数型言語があります。)
ドナルフェローズ

1
OOPは手続き型のものを入れるだけの箱とは言えませんか?
エリックReppen

OOPでは、メソッドを作成できます。OOPが手続き型プログラミングよりも弱いのはなぜですか?
メルトアカカヤ

48

私見それは個人の好みと考え方の問題です。オブジェクト指向にはあまり問題ありません。

私たち(または少なくとも私)は、遭遇するもの間の関係の観点から世界を概念化しますが、OOPの焦点は個々のクラスとその階層を設計することです。

私見これはそうではありませんが、一般的な認識かもしれません。オブジェクト指向という用語の発明者であるアラン・ケイは、オブジェクト自体ではなく、オブジェクト間で送信されるメッセージを常に強調していました。そして、少なくとも私にとって、メッセージは関係を示しています。

日常生活では、OOPの無関係なクラスのインスタンスになるはずのオブジェクト間に、ほとんどの関係とアクションが存在することに注意してください。

オブジェクト間に関係がある場合、それらは定義ごとに関連付けられます。OOでは、2つのクラス間の関連付け/集約/使用の依存関係で表現できます。

動詞が2つのオブジェクトに作用して何らかの結果/アクションを生成するアクション(関係)である2価(たとえば、「私はあなたに花を贈った」など)の動詞の観点で考えます。焦点はアクションにあり、2つ(または3つ)の[文法]オブジェクトの重要性は等しくなります。

しかし、それらは文脈において明確に定義された役割を持っています:主題、目的、行動など。「私はあなたに花を与えました」または「あなたは私に花を与えました」は同じではありません-)

それとは対照的に、最初に1つのオブジェクト(名詞)を見つけて、別のオブジェクトに対して何らかのアクションを実行するように指示する必要があるOOPとは対照的です。考え方は、名詞で動作するアクション/動詞から名詞で動作する名詞にシフトします。これは、すべてが受動的または再帰的な音声で言われているようです。たとえば、「テキストはターミナルウィンドウで表示されています」。または、「テキストは端末ウィンドウに表示されます」。

私はこれに同意しません。私見の英語の文「ビル、地獄に行く」bill.moveTo(hell)ではなく、プログラムコードでより自然に読みますmove(bill, hell)。前者は、実際には元のアクティブな音声により類似しています。

したがって、terminalWindow.show(someText)またはsomeText.show(terminalWindow)と言うかどうかを決定する必要があります。

繰り返しますが、端末にテキストを表示するように要求したり、端末に表示するようにテキストを要求することは同じではありません。私見では、どちらがより自然であるかは明らかです。

これらの問題を考えると、OOPを行う現在の主流の方法が非常に一般的になったのはどうしてですか。

OO開発者の大多数がオブジェクト指向をあなたとは違って見ているからでしょうか?


15
オブジェクト間のメッセージとその重要性を
アランケイ

3
@zvrba、確かに、他のオブジェクト指向の先駆者もいましたが、それはこの議論の要点ではありません。「最も自然なことは、表示されるテキストを要求することです。」-これで、OOPで「不自然」だと主張したのと同じ受動態を使用しています。
ペテルトレック

5
@zvrba、「あなたは常に「エージェント」がいる」と言いますが、それらのエージェント(オブジェクト)を識別して命名し、言語の第一級市民として扱うというオブジェクト指向アプローチに抗議します。私にとってこれは問題領域のモデリングの一部です-とにかくそれを行う必要があり、その後、言語がオブジェクト指向かどうかに応じて、結果のドメインモデルを異なる方法でコードにマッピングします。
ペテルトレック

6
@zvrba、それ自体はオブジェクト指向ではなく、異なるオブジェクトの役割と責任について決定するのは開発者/設計者です。オブジェクト指向のアプローチを使用すると、ナイフを使用して細かいパンや出血した指を得ることができるのと同じように、良いまたは悪いドメインモデルとデザインが得られます-それは単なるツールであるため、ナイフを責めることはありません。また、モデルの概念/オブジェクト/エージェントは、現実世界の物事の抽象化であり、特定の「興味深い」側面のみに焦点を合わせて、常に制限され、歪められていることに注意してください。
ペテル

6
@zvrba、車は確かにそれ自体の意志で始まりません- Carオブジェクトがstart()そのメソッドが誰かによって明示的に呼び出されたときだけそうするように。
ペテルトレック

10

一部のプログラマーは、問題を解決する方法ではなく、コンピューターの問題を解決する方法を考えているため、OODが難しいと感じています。

...しかし、OOPの焦点は個々のクラスとその階層を設計することです。

OODはそれについてではありません。OODとは、物事の振る舞いや相互作用を理解することです。

動詞が2つのオブジェクトに作用して何らかの結果/アクションを生成するアクション(関係)である2価(たとえば、「私はあなたに花を贈った」など)の動詞の観点で考えます。焦点はアクションにあり、2つ(または3つ)の[文法]オブジェクトの重要性は等しくなります。

OODの焦点は常にアクションにあり、アクションはオブジェクトの動作です。オブジェクトは、その振る舞いなしでは何もありません。OODの唯一のオブジェクト制約は、すべてが何かによって行われなければならないということです。

何かをすることよりも重要だとは思っていません。

しかし、実際にshow(terminalWindow、someText)を意味するのに、操作に影響を与えずにこのような些細な決定を人々に負わせるのはなぜですか?

私にとって、それは異なる表記の同じことです。誰がショーをするのか、誰がショーをするのかを決める必要があります。それを知ったら、OODに決定はありません。ウィンドウはテキストを表示-> Window.Show(text)。

世の中の多くのもの(特にレガシー分野)は、そうでないときはオブジェクト指向だと言っています。たとえば、大量のOODを実装しないC ++コードが大量にあります。

OODは、コンピューターの問題を解決するという考え方から抜け出せば簡単です。何かをすることで問題を解決しています。


10
私は問題を解決する方法を考えることを好むので、OODが好きではありません。問題のあるドメインの自然言語を、オブジェクト、メッセージ、継承などの異質な世界に変換する方法を考えたくありません。自然に存在しない階層的分類法を発明したくありません。問題を自然言語で記述し、可能な限り簡単な方法で解決したいと思います。そして、ところで、世界は「ものをするもの」だけでできているわけではありません。現実に対するあなたの見方は非常に狭いです。
SKロジック

7
@Matt Ellen、私は「もの」ではなく、「何か」を「しない」エンティティの振る舞いをモデル化するプログラムを書いています。どれでも不変 の実体は何もしません。数学的な純粋な関数は何もしません-それはあるセットから別のセットへの単なるマッピングであり、この世界はそのような関数によって大部分が記述されます。論理的な形式主義は何も「しません」。はい、OODは私を助けません。なぜなら、はるかに強力な抽象化とモデルを使用できるからです。原始的で制限された限定的なOODに戻ると、深刻な障害になります。
SKロジック

2
@Matt Ellen、はい、世界は「物事を行うもの」、または「メッセージを介して相互作用するオブジェクト」のコレクションとして見た方が良いという奇妙な主張を裏付ける参考文献を見たいです。それは完全に不自然です。科学的理論(この段階では可能な限り実世界のモデリングに近いため)を取り、用語を使用して書き直してみてください。結果は不器用で厄介です。
SKロジック

4
@ Antonio2011a、可能なすべての問題領域を効率的にカバーできる単一のプログラミングまたはモデリングパラダイムはありません。OOP、機能、データフロー、一次論理、その他何でも-それらはすべて問題領域固有のパラダイムであり、それ以上のものではありません。私は問題解決への多様性とオープンマインドなアプローチのみを提唱しています。あなたの思考を単一のパラダイムに絞り込むことは愚かなことです。普遍的なアプローチに近いもの、単一セマンティックフレームワークにあなたを制限していないが、されen.wikipedia.org/wiki/Language-oriented_programming
SK-ロジック

3
@Calmariusなぜコンピューターのプログラミングを簡単にするのですか?それはばかげている。より難しい仕事をしなければならないのは人間です。
マットエレン

7

たぶん、私はポイントを得ることができませんが、:

OOPに関する最初の本(90年代前半、ボーランドのPascalの薄いマニュアル)を読んで、そのシンプルさと可能性に単純に驚きました。(以前は、Cobol、Fortran、アセンブリ言語、その他の先史時代のものを使用していました。)

私にとって、それはかなり明確です:犬は動物であり、動物は食べなければなりません、私の犬は犬なので、食べなければなりません...

一方、プログラミング自体は本質的に不自然です(つまり、人工的です)。人間のスピーチも人為的なものです(私を非難しないでください、私たちは皆、他の人から自分の言語を学んでいます。一部の科学者によると、人間の心は最初に学んだ言語によって形成されます。

私は認める、現代のオブジェクト指向言語のいくつかの構造は少し厄介ですが、それは進化です。


1
cobolからfortranに移行し、次にアセンブリ(およびその他)に移行するためのあなたの仕事は何でしたか?
ルーク

1
注文間違い。実際、私はBasicから始めて、Fortranに移り、次にAssemblyとCobolに移りました(そうです、正しい順序です:最初にAssembly)。私の人生で最初のコンピューターは、「巨大な」メインフレーム、256kBのメモリー、タイプライターのコンソール、パンチカードの供給でした。私がシステムプログラマーになるのに十分なレベルに達したとき、PC-ATと呼ばれる疑わしいものが私の机に上陸しました。だから私はGW-Basic、Turbo-Pascalなどに突入していた。
-Nerevar

1
私はそれを気にしていませんでした。あなたの仕事ドメインにもっと; 原因は、COBOL(ビジネス指向)、Fortran(科学ドメイン)、アセンブラー(より多くのcs指向)、そして他の人々を扱った多くの人々(実際には誰でも)を知りません。それにもかかわらず、彼らはプロのプログラマーであろうとなかろうと。
ルーク

1
不可解:以前に言語アプローチの決定がなされていたチームやプロジェクトに参加する。そして、彼らが使用していたツールについてのある種の非自明なレベルの好奇心。
-Nerevar

6

私にとって難しいことの1つは、OOPは世界をモデル化することだと考えていたことです。私はそれを正しくしなかった場合、何かが来て、ロバで私を噛むかもしれないと思った(事は真実かそうでないかのどちらか)。私はすべてがオブジェクトまたはエンティティであるふりをする問題を非常に認識していました。これにより、OOPでのプログラミングについて非常に暫定的で自信が持てなくなりました。

それから私はSICPを読んで、それが本当にデータ型とそれらへのアクセスの制御に関するものであるという新しい理解に至りました。OOPでは世界をモデル化しているという誤った前提に基づいていたため、私が解決したすべての問題。

私は今でも、この誤った前提が私に与えた巨大な困難に驚嘆します(そして、私はそれをどのように見守ったか)。


世界をモデル化しようとする危険性を指摘していただきありがとうございます。
ショーンマクミラン

4

はい、OOP自体は非常に不自然です-現実の世界は、階層的な分類法で完全に作られているわけではありません。それのいくつかの小さな部分はそのようなもので作られており、その部分はオブジェクト指向に関して適切に表現できる唯一のものです。残りはすべて、このような些細で限定的な考え方に自然に適合することはできません。自然科学をご覧ください。現実世界の複雑さを最も簡単な方法で、または少なくとも理解できる方法で表現するために、いくつの異なる数学言語が発明されたかをご覧ください。そして、それらのほとんどは、オブジェクトやメッセージの言語に簡単に翻訳できません。


5
まあ、それは実世界を正確に表現しようとするあらゆる形式の表記法にも同様に当てはまります。
ペテルトレック

1
@PéterTörök、まさに私のポイント。すべてをカバーする単一の形式はありません。あなたはそれらをすべて、恐ろしい群衆のすべてで使わなければなりません。そして、それが私が言語指向のプログラミングを信じている理由です-それは、さまざまな、しばしば互換性のない形式主義を堅実なコードエンティティに取り入れることを可能にします。
SKロジック

1
すべてを階層的な分類に分類できます。トリックは理にかなっているスキームを考え出しています。多くの場合、多重継承が関係します。ソフトウェアと現実の世界の大きな違いは、現実の世界では、多くの場合、分類スキームを推測または発見する必要があることです。ソフトウェアでは、それらを発明します。
カレブ

1
「階層的分類法」のような用語を使用することで、よくあなたは継承を考えていると思います。継承について考えるのは本当に難しいです。そのため、人々は継承よりも合成を使用することを提案します。
フランクシェラー

1
@Frank:現実の世界には多くのタイプの階層的分類法があり、そのうちの継承は1つだけです。これをすべて適切に行うには、OOPよりも優れたツール(オントロジー的推論など)が必要であり、数千年の
Donal Fellows

4

私たち(または少なくとも私)は、遭遇するもの間の関係の観点から世界を概念化しますが、OOPの焦点は個々のクラスとその階層を設計することです。

あなたは(IMO)間違った前提から始めています。オブジェクト間の関係は、オブジェクト自体よりも間違いなく重要です。オブジェクト指向のプログラム構造を提供するのは関係です。オブジェクトのクラスがそのオブジェクトができることを決定するため、継承、クラス間の関係はもちろん重要です。しかし、クラスによって定義された境界内でオブジェクトが実際に行うこと、したがってプログラムの動作を決定するのは、個々のオブジェクト間の関係です。

オブジェクト指向のパラダイムは、オブジェクトの新しいカテゴリを考えるのが難しいためではなく、オブジェクトのグラフを想像し、オブジェクト間の関係がどうあるべきかを理解するのが難しいため、最初は難しい場合があります。それらの関係を記述する方法。これが、デザインパターンが非常に役立つ理由です。設計パターンは、ほぼ完全にオブジェクト間の関係に関するものです。パターンは、より高いレベルでオブジェクトの関係を設計するために使用できるビルディングブロックと、それらの関係を記述するために使用できる言語の両方を提供します。

物理的な世界で働く創造的な分野でも同じことが言えます。誰でもたくさんの部屋をまとめて、それを建物と呼ぶことができます。部屋には最新の備品がすべて完備されているかもしれませんが、それでは建物は機能しません。建築家の仕事は、それらの部屋と建物の環境を使用する人々の要件に関して、それらの部屋の間の関係を最適化することです。これらの関係を正しくすることが、機能的および美的観点の両方から建物を機能させるものです。

OOPに慣れるのに苦労している場合は、オブジェクトがどのように適合し、その責任がどのように調整されているかについてさらに考えることをお勧めします。まだデザインパターンについて読んでいない場合は、読んだパターンをすでに見たことに気付くでしょう。ただし、名前を付けると、木だけでなく、スタンド、警官、茂み、森、木立、森、そして最終的には森。


3

これは、OOPの問題の一部にすぎません。

基本的に、機能は二流の市民となり、これは悪いことです。

現代の言語(ruby / python)はこの問題を抱えておらず、関数をファーストクラスオブジェクトとして提供し、クラス階層を構築せずにプログラムを作成できるようにします。


OOPは私にとって非常に自然に思えます。実際、プログラミングタスクについて他の方法で考えるのは難しいです。それでも、長年にわたって、OOPは動詞よりも名詞を強調する傾向があることを理解するようになりました。2006年からこの暴言は私がこの区別を理解する助け:steve-yegge.blogspot.com/2006/03/...
テキサス州ではジム・

3

OOPは難しくありません。うまく使用するのが難しいのは、プログラマがランダムな格言を聞いて、神の4人のギャング、祝福されたマーティン・ファウラー、または読んでいる他の誰でも。


3

編集済み

まず第一に、OOPが難しいとか、他のプログラミングパラダイムよりも難しいとは思っていなかったと言いたいと思います。プログラミングは、現実世界の問題を解決しようとするものであり、現実世界は非常に複雑であるため、本質的に困難です。一方、この質問を読んだとき、私は自問しました:OOPは他のパラダイムよりも「自然」ですか?したがって、より効果的ですか?

私はかつて、命令型プログラミング(IP)とオブジェクト指向プログラミング(OOP)の比較研究に関する記事を見つけました(参照として投稿できるように、もう一度見つけたいと思います)。彼らは基本的に、異なるプロジェクトでIPとOOPを使用するプロのプログラマの生産性を測定し、その結果、大きな違いは見られませんでした。そのため、2つのグループ間で生産性に大きな違いはなく、本当に重要なのは経験であるという主張でした。

一方、オブジェクト指向の支持者は、システムの初期開発中はOOPが命令よりも時間がかかる場合があると主張しますが、長期的にはデータとオペレーション。

私は主にOOP言語(C ++、Java)で作業しましたが、大規模なプロジェクトで試したことがないのに、PascalやAdaを使って生産性を上げることができると感じることがよくあります。

それとは対照的に、最初に1つのオブジェクト(名詞)を見つけて、別のオブジェクトに対して何らかのアクションを実行するように指示する必要があるOOPとは対照的です。

[切る]

したがって、OOP(クラスベース、シングルディスパッチ)を行う主流の方法は難しく、それは非自然的であり、人間の世界に対する考え方に対応していないためです。CLOSの汎用メソッドは私の考え方に近いものですが、残念ながら、これは一般的なアプローチではありません。

この最後の段落をより注意深く読んだとき、あなたの質問の要点をようやく理解したので、答えを一から書き直さなければなりませんでした。:-)

複数のオブジェクトが1つだけではなくメッセージを受信する他のオブジェクト指向の提案を知っています。つまり、メッセージを受信するときに複数のオブジェクトが対称的な役割を果たします。はい、これは私にとってより一般的で、おそらくより自然な(制限の少ない)OOPアプローチのようです。

一方、「複数ディスパッチ」は「単一ディスパッチ」を使用して簡単にシミュレートでき、「単一ディスパッチ」は実装が簡単です。これが「複数のディスパッチ」が主流になっていない理由の1つかもしれません。


3

排他的にOOPパラダイムを探すのをやめて、JavaScriptを試してください。

現在、UIオブジェクトがイベントドリブンインターフェイスで動作しているスキームがあります。つまり、起動すると内部的に定義されたアクションが発生する典型的なパブリックメソッドのようになります。しかし、起動されると、実際に発生するのは、オブジェクト自体でイベントをトリガーし、そのオブジェクト内の事前定義されたハンドラーが応答することです。このイベントと、他のリスナーに渡されるプロパティをアタッチできるイベントオブジェクトは、聞きたいものなら何でも聞くことができます。オブジェクトを直接リッスンするか、一般的にそのイベントタイプをリッスンできます(イベントは、ファクトリによって構築されたすべてのオブジェクトがリッスンできる汎用オブジェクトでもトリガーされます)。そのため、たとえば、ドロップダウンリストから新しいアイテムを選択するコンボボックスがあります。

あなたが望むなら(そして、私は通常望んでいないことを発見して驚いた-それはイベントがどこから来たのかわからないときの読みやすさの問題だ)あなたは完全なオブジェクトを分離し、渡されたイベントオブジェクトを介してコンテキストを確立することができます。とにかく、複数のレスポンダーを登録できるようにすることで、単一ディスパッチを回避しています。

しかし、私はこれをOOPだけで行っているわけではなく、JSは定義によっては「適切に」OOPでもありません。私の意見では、より高いレベルのアプリ開発のために適切なのは、あなたの状況に合ったものにパラダイムを曲げる力を持っていることであり、気になればクラスをうまくエミュレートできます。しかし、この場合、機能(ハンドラーを渡す)の側面をOOPと混合しています。

さらに重要なことは、私が持っているものが非常に強力だと感じることです。あるオブジェクトが別のオブジェクトに作用するという観点では考えていません。私は基本的に、オブジェクトが何に関心を持っているかを決定し、物事を整理するのに必要なツールを与え、ミキサーにドロップして相互に反応させるだけです。

だから私が言っているのはこれだと思う:それはswitch文のような問題ではない。ミックスアンドマッチです。問題は言語と流行であり、それはあなたがそれを一つの物だと信じて欲しいのです。たとえば、ジュニアのJava開発者は、デフォルトで常に適切に実行していると思うのに、どうしてOOPを本当に評価できますか?


2

私に説明された方法は、トースターと車でした。両方ともスプリングがあるので、「スプリング」オブジェクトがあり、サイズ、強度などが異なりますが、両方とも「スプリング」であり、そのメタファーを車に拡張すると、多くの車輪があります(ホイール、明らかに、ステアリングホイール、電気ショック療法)とそれは多くの理にかなっています。

プログラムはオブジェクトのリストと考えることができ、視覚化するほうがはるかに簡単です。「それは何かをするもののリストなので、前に見た指示のリストとは異なります」

OOPの本当の問題は、それがどのように人々に説明されるかだと思います。多くの場合、(私のユニクラスで)「それは小さなことを行う多くのクラスについてであり、それからオブジェクトを作成できます」と説明されており、本質的に抽象的なものを使用しているため、多くの人を混乱させますこれらの概念を説明する用語であり、5歳のときにレゴで遊んでいるときに人々が把握していた具体的なアイデアではありません。


2
スプリングには何百万ものフォームがあり、そのすべてが同様の機能を果たします。これは関数型プログラミングの完璧な例だと思います。
-l0b0

2

これは、分類を通じて世界を考える自然な方法です。それは多かれ少なかれオブジェクト指向についてです。プログラミングは難しいため、OOPは難しいです。


しかし、一部のオブジェクトに共通の属性または共通の動作があるかどうかに応じて分類していますか?名前と姓を持っているものはすべて人ですか?動物を歩くものはすべてありますか?
-zvrba

分類に関しては、特定の動作を実行できることが属性です。シマウマと馬は繁殖できますが、子孫は雑種です。同じ種ではないことがわかっている場合を除き、交配機能の所有に基づいてこの結果を予測することは非常に困難です。
-JeffO

1
@zvrba:コメントで提起された質問に対する私の答えはそれit doesn't matterです。名前と姓を持つものはすべて、人々だけを気にするすべてのプログラムの人です。人または非人の知識を持たないプログラムの場合、それはIHasNameAndSurnameです。オブジェクトは当面の問題を解決するだけで済みます。
トムW

@Jeff O同じ種/品種/個体群内でもばらつきがあり、理想的な(必須の)例はありません。ですから、はい、オブジェクト指向は実際の自然とは異なりますが、人間の自然な考え方にぴったりです。
トムホーティン-タックライン

2

人々がOOPを使用して現実を表現しようとすると、いくつかの困難が生じると思います。誰もが知っいるように、車には4つの車輪とエンジンがあります。誰もが知っている車ができることStart()Move()およびSoundHorn()

私はいつもこれをやろうとするのをやめるべきだと気付いたとき、私の頭の中で光が鳴りました。オブジェクトは、名前を共有するものではありません。オブジェクトは、問題の範囲に関連する十分に詳細なデータのパーティションです(つまり、そうあるべきです)。このought問題を解決するには、何より劣らず、持っていないし、それを必要としない正確に何を持っています。ある動作の原因となるオブジェクトを作成すると、同じ動作が曖昧な第三者の仕事(「ポルターガイスト」と呼ばれることもある)よりも多くのコード行が作成される場合、ポルターガイストはチップを獲得します。


1

複雑さを管理するには、機能をモジュールにグループ化する必要がありますが、これは一般に難しい問題です。資本主義についての古い言い回しのように、OOPはソフトウェアを整理するための最悪のシステムです。

名詞内の相互作用をグループ化する理由は、2つの名詞のどちらをグループ化するかについてあいまいさが頻繁にありますが、名詞の量はたまたま管理可能なサイズのクラスになり、動詞によるグループ化はどちらかを生成する傾向があるためです単発のような非常に小さなグループ、またはshowのような関数の非常に大きなグループ。継承などの再利用の概念は、名詞でグループ化するときに、はるかに簡単に解決することもあります。

また、ショーをウィンドウで表示するかテキストで表示するかを決定する問題は、理論上よりも実際上、ほとんど常に明確です。たとえば、ほぼすべてのGUIツールキットグループはコンテナで追加されますが、ウィジェットで表示されます。コードを他の方法で記述しようとすると、抽象的に考えると2つの方法は互換性があるように見えますが、その理由はかなり早く明らかになります。


2
適切な モジュールシステムを見たことがありますか?OOPが利用可能な最高のものであるとどのように言えますか?SMLモジュールは、はるかに強力です。ただし、ほとんどの場合、AOPパッケージでさえ、OOPの小さなヒントがなくても十分です。
SKロジック

@ SK-logic、私はあなたが非常に正確な定義に夢中になっていると思う。OOPとは、クラスを意味するのではなく、「動詞」を操作対象の「名詞」で論理的にグループ化し、操作対象の名詞に基づいてそれらの動詞を再利用および特殊化できることを意味します。クラスはたまたまその最も有名な実装ですが、唯一の実装ではありません。私はSMLモジュールの無知を認めますが、それを調べたときに最初に見た例は、機能するように構文を変更したオブジェクト指向設計書から来る可能性のあるキューの実装でした。
カールビーレフェルト

残念なことに、OOPに属していないものに対して不幸なOOPを与えすぎるのは不公平です。モジュールは素晴らしい発明です。一流のモジュールは素晴らしいです。しかし、OOPはそれらとはまったく関係ありません。一部のOOP言語はモジュール機能のいくつかを採用しましたが(特に注目すべきは名前空間)、モジュールはクラスよりもはるかに一般的で強力な概念です。あなたはクラスが「最高」であると言ったが、それは真実とは程遠い。ファーストクラスのモジュールははるかに優れています。そして、もちろん、型システムは、サブタイプ化されたオブジェクトを持つ単なるOOよりもはるかに広くて深いです。
SKロジック

1
「それは資本主義についての古い言い回しのようなものです。OOPは、私たちが試した他のすべてを除けば、ソフトウェアを組織化するための最悪のシステムです。」:おそらく十分に長くやっていない :-)
ジョルジオ

1
私は、あなたが「民主主義」を意味だと思う:quotationspage.com/quote/364.html
nicodemus13

1

いいえ。プログラミングを使用して問題を解決する方法はいくつかあります:機能的、手続き的、論理的、OOP、その他。

現実の世界では、人々は機能的パラダイムを使用する場合がありますが、手続き的パラダイムを使用する場合もあります。そして時々混乱した。そして最終的に、それらをプログラミングの特定のスタイルまたはパラダイムとして表します。

LISPで使用される「すべてがリストまたはアイテムです」というパラダイムもあります。関数型プログラミングとは別のものとして言及したいです。PHPは連想配列でそれを使用します。

OOPと「すべてがリストまたはアイテム」のパラダイムは、一部の人工知能クラスで覚えているように、より自然なプログラミングスタイルの2つと考えられます。

「OOPは自然ではない」、OOPについて学ぶ方法、またはOOPについて教えられた方法は間違っているかもしれませんが、OOP自体ではありません。


1

これらの問題を考えると、OOPを行う現在の主流の方法が非常に一般的になったのはどうしてですか。そして、もしあれば、それを退位させるために何ができるでしょうか?

OOPが人気を博したのは、OOPがプログラムを整理するためのツールを提供しているためです。また、メソッドの内部に手続き構造を持ち、それらを囲むオブジェクト指向の構造を持つ言語を作成することも比較的簡単でした。これにより、プログラミングの方法をすでに知っているプログラマーは、オブジェクト指向の原則を1つずつ取り上げることができます。また、これにより、クラスまたは2つにラップされた手続き型プログラムである、名前のみのOOプログラムが多数作成されました。

OOを退治するには、ほとんどのプログラマーが今日知っているもの(ほとんどOOを使用したほとんどの手順)から好みのパラダイムに段階的に簡単に移行できる言語を構築します。一般的なタスクを実行するための便利なAPIが提供されていることを確認し、適切に宣伝してください。人々はまもなくあなたの言語でX-in-name-onlyプログラムを作成するでしょう。その後、人々が実際にXを実行するのに何年もかかることが予想されます。


OPはOOは一般に悪いので廃止すべきだと主張しませんが、「現在の主流のOOPのやり方」は最も自然なものではありません(「複数のディスパッチ」と比較して)。
ジョルジオ

OPは、型階層の定義にも過度に焦点を当てているようです。ここでは、最高のオブジェクト指向プログラムは、インターフェイスと構成に依存する傾向があります。マルチディスパッチがXの場合、複数のディスパッチに関連するスキルを徐々に習得できる言語を作成することが、環境を変更するための鍵となります。
ショーンマクミラン

1

OOPおよびOOP言語にも問題があると思います。

正しく理解すれば、OOPとは、プッシュ可能なプッシュボタン(メソッド)を持つブラックボックス(オブジェクト)に関するものです。これらのブラックボックスを整理するのに役立つクラスがあります。

1つの問題は、プログラマーがプッシュボタンを間違ったオブジェクトに置いた場合です。端末はそれ自体にテキストを表示できません。テキストは端末に表示できません。それを行うことができるオペレーティングシステムのウィンドウマネージャーコンポーネント。端末ウィンドウとテキストは単なる受動的なエンティティです。しかし、このように考えると、ほとんどのエンティティが受動的なものであり、実際に何か(または単に1つ:コンピューター)を実行するオブジェクトはごくわずかしかありません。実際、Cを使用する場合は、Cをモジュールに編成します。これらのモジュールは、少数のオブジェクトを表します。

もう1つのポイントは、コンピューターが命令を順番に実行するだけであることです。オブジェクトVCRTelevisionオブジェクトがあるとします。ビデオをどのように再生しますか?おそらく次のようなものを書くでしょう:

connect(television, vcr);
vcr.turnOn();
television.turnOn();
insert(vcr, yourFavoriteCasette);
vcr.play();
while (vcr.isPlaying()) {} // Wait while the VCR is playing the casette.
vcr.eject();
vcr.turnOff();
television.turnOff();

これは簡単ですが、そのためには少なくとも3つのプロセッサ(またはプロセス)が必要です。1つはあなたの役割を果たし、2つ目はVCR、3つ目はTVです。ただし、通常、コアは1つだけです(少なくとも、すべてのオブジェクトには十分ではありません)。大学では、クラスメートの多くは、プッシュボタンが高価な操作を行うとGUIがフリーズする理由を理解していませんでした。

ですから、オブジェクト指向のデザインは世界を非常にうまく表現していると思いますが、それはコンピューターにとって最高の抽象化ではありません。


0

MVCパターンの発明者によって発明されたDCI(データ、コンテキスト、および相互作用)を見てください。

DCIの目標は(Wikipediaから引用):

  • オブジェクト(名詞)の上に、システムの動作に最高のステータスを与えます
  • 急速に変化するシステムの動作(システムが行うこと)のコードと、ゆっくり変化するドメインの知識(システム)のコードを、1つのクラスインターフェイスに結合するのではなく、明確に分離する。
  • クラスの考え方ではなく、人々の精神モデルに近いオブジェクトの考え方をサポートする。

ここだ著者良い記事はここだある小さな実装例(.NET)あなたには、いくつかのコードを見たい場合。見た目よりもずっとシンプルで、とても自然に感じられます。


0

OOPは、人々が世界について考える方法に自然に対応しているとよく聞くことができます。しかし、私はこの声明に強く反対します(...)

本や他の場所で何十年も伝道されているので、私も反対します。それでも、NygaardとDahlはそのように考えていたと思います。彼らは、当時の選択肢と比較してシミュレーションの設計を考えることがいかに簡単かに焦点を当てていたと思います。

(...)しかし、OOPの焦点は個々のクラスとその階層を設計することです。

この主張は、OOPの一般的な誤解がどれほど一般的であり、オブジェクト指向が定義に対してどれほど敏感であるかを考えると、賢明な領域に入ります。私はこの分野に10年以上携わっており、業界の仕事とプログラムに関する学術研究の両方を行っています。言語、そして私は何年もかけて「メインストリームOO」を学習しなかったと言うことができます。なぜなら、私はそれが以前のクリエイターが目指していたものとどれほど違う(そして劣っている)ことに気付き始めたからです。主題の最新の治療については、W。クックの最近の取り組みを参照します。

「「オブジェクト」および「オブジェクト指向」の簡素化された最新の定義の提案 http://wcook.blogspot.com.br/2012/07/proposal-for-simplified-modern.html

これらの問題を考えると、OOPを行う現在の主流の方法が非常に一般的になったのはどうしてですか。

QWERTYキーボードが普及したのと同じ理由か、DOSオペレーティングシステムが普及したのと同じ理由かもしれません。物事は、その特性にもかかわらず、人気のある乗り物に乗るだけで、人気を博します。そして、時々、似ているがより悪いバージョンのものが実際のものと見なされます。

そして、もしあれば、それを退位させるために何ができるでしょうか?

優れたアプローチを使用してプログラムを作成します。オブジェクト指向のアプローチを使用して同じプログラムを作成します。重要なあらゆる側面において、前者が後者よりも優れた特性を持っていることを示します(システム自体の特性と工学的特性の両方)。選択されたプログラムが適切であり、提案されたアプローチが他の種類のプログラムに適用された場合、高品質の特性を維持することを示します。分析を厳密に行い、必要に応じて正確で受け入れられた定義を使用してください。

最後に、調査結果を共有してください。


-1

Javaを取る:オブジェクトは一種の抽象化のボトルネックであり、ほとんどの「もの」は厳密にオブジェクトのサブコンポーネントであるか、オブジェクトをサブコンポーネントとして使用します。オブジェクトは、これら2種類の物事間の抽象化層全体に対して十分な多目的でなければなりません。多目的とは、それらが具体化するメタファーが1つもないことを意味します。特にJavaは、オブジェクト(&クラス)をコードの呼び出し/ディスパッチの唯一のレイヤーにします。オブジェクトが体現するこの量は、率直に言って、非常に複雑になります。それらの有用な説明は、何らかの特殊な形式または制限された形式に制限する必要があります。

継承とインターフェースの階層は、オブジェクトをサブコンポーネントとして使用する「もの」です。これは、オブジェクトの一般的な理解を引き出すための方法ではなく、オブジェクトを記述するための1つの特殊な方法です。

「オブジェクト」は、「OOランゲージ」で多かれ少なかれ普遍的な多目的の抽象化であるため、多くのものがあると言える。それらがローカルの可変状態を含むために使用される場合、または外部の世界状態にアクセスするために使用される場合、それらは「名詞」に非常によく似ています。

対照的に、プロセスを表すオブジェクト(「暗号化」、「圧縮」、「ソート」など)は「動詞」のように見えます。

一部のオブジェクトは、名前空間としての役割に使用されます。たとえば、Javaに「静的」関数を配置する場所です。

私は、Javaがオブジェクトのメソッド呼び出しでは重すぎて、オブジェクトをディスパッチするという議論に同意する傾向があります。これはおそらく、ディスパッチを制御するのにHaskellの型クラスを好むからです。これはディスパッチの制限であり、Javaの機能ですが、ほとんどの言語、またはほとんどのオブジェクト指向言語ではありません。


-3

私はOOPに関する多くのオンライン討論を目撃し、参加しました。OOPの支持者は通常、適切な手続きコードの書き方を知りません。高度にモジュール化された手続き型コードを書くことは可能です。コードとデータを分離し、関数が独自のデータストアにのみ書き込みを行えるようにすることは可能です。手続き型コードを使用して継承の概念を実装することができます。さらに重要なことは、手続き型コードはより細く、速く、デバッグしやすいことです。

厳密な命名規則を使用して単一ファイルモジュールを構築する場合、手続き型コードはオブジェクト指向よりも記述および保守が容易であり、同じかそれ以上の速度で実行されます。また、アプリケーションの実行時には、スクリプトに含まれるクラスの数に関係なく、常に手続き型であることを忘れないでください。

次に、真のオブジェクト指向ではなく、多重継承のような偽物をハックに依存しているPHPのような言語の問題があります。言語の方向性に影響を与えるビッグショットは、PHPを一貫性のないルールのパッチワークに変え、当初意図したものよりも大きくなりすぎました。開発者が手続き型テンプレート言語として意図されたもののために巨大なテンプレートクラスを書くのを見たとき、私は微笑まざるを得ません。

適切に記述されたOOコードと不十分に記述された手続き型コードを比較すると、常に間違った結論に達します。オブジェクト指向設計を保証するプロジェクトはほとんどありません。IBMであり、複数の開発者が何年も維持する必要がある巨大なプロジェクトを管理している場合は、オブジェクト指向を選択してください。クライアント向けに小さなブログやショッピングWebサイトを作成している場合は、よく考えてください。

元の質問に答えるために、OOPは、実際のプログラミングのジレンマを、本来の100倍複雑なソリューションに頼ることなく解決しないため、困難です。多くのプログラミング問題に対する最も強力なソリューションの1つは、グローバルデータの賢明な使用です。しかし、新しい波の大学の卒業生は、それが大きなノーだと言うでしょう。あなたが不器用なプログラミングバニーである場合にのみ、グローバルに利用可能なデータは危険です。厳密な規則のセットと適切な命名規則がある場合は、すべてのデータをグローバルにすることができます。

オブジェクト指向プログラマにとって、16Kの最大使用可能メモリを確保するために、アセンブラーでチェスプレイアプリケーションを記述する方法を知ることは必須の要件です。その後、脂肪を削減し、怠を減らし、独創的なソリューションを生成する方法を学びます。

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