質問

私の理解では、OOP は大規模プロジェクトで最も一般的に使用されるパラダイムです。また、大きなシステムの一部の小さなサブセットでは他のパラダイムが使用されていることも知っています (例:SQL、これは宣言型です)、また、低レベルのコンピューティングでは OOP が実際には実現不可能であることも認識しています。しかし、通常、より高いレベルのソリューションの部分は、ほとんどの場合、OOP 形式でまとめられているように思えます。

本当に非 OOP パラダイムが実際に実現されるシナリオはありますか? より良い 大規模なソリューションを選択しますか?それとも最近ではそんなことは前代未聞ですか?

CS の勉強を始めて以来、ずっと疑問に思っていました。OOP は決して超えられることのないプログラミングの極楽であるという感覚を抱くのは簡単です。

役に立ちましたか?

解決

私の意見では、OOPがこのように広く使用されている理由は、それが仕事のための適切なツールだということはあまりありません。私はそれが解決策は、彼らが理解した方法で顧客に説明することができることをより多くのだと思います。

CARは、エンジンを有する車両です。それはすべて1でのプログラミングと現実の世界だ!

これはそれほどエレガントなプログラミングと現実の世界に合うことができる何かを理解するのは難しいます。

他のヒント

Linuxは非常に多くのOOPではありません大規模なプロジェクトです。そして、それはどちらかそれから得るために多くを持っていないでしょう。

私はそれがカプセル化、データ隠蔽、コードの再利用、モジュール性などの優れたプログラミング手法で自身を関連付けられているので、OOPは、それとの良好なリングを持っていると思うet.c.しかし、これらの美徳は決してOOPに固有のものではありません。

あなたはジョー・アームストロングによって書かれたErlangのを見て、必要がある場合があります。

ウィキペディアます:

  

「アーランは、汎用的です   並行プログラミング言語と   ランタイムシステム。シーケンシャルサブセット   関数型言語であるErlangのの、   厳格な評価と、単一   割り当て、および動的型付け。」

ジョー・アームストロングます:

  

「の問題であるため   オブジェクト指向言語彼らがきています   すべてのこの暗黙の環境を持っています   彼らは彼らと一緒に持ち歩きます。君は   バナナを望んでいたが、何を得たことでした   ゴリラはバナナを保持し、   全体のジャングル。」

OOPの約束は、コードの再利用と簡単にメンテナンスしました。私はそれが配信を確認していません。私たちは、さまざまなベンダーのあちこちに取得するために使用するCライブラリとほぼ同じであるとして、このようなドットネットとして物事を見ます。あなたがしたい場合は、そのコードの再利用を呼び出すことができます。メンテナンスに関しては悪いコードは悪いコードです。 OOPは助けにはならなかった。

私はOOPの最大のファンだ、と私は毎日OOPを練習します。 それは現実の生活に似ているので、コードを書くための最も自然な方法です。

けれども、私はOOPの仮想化は、パフォーマンスの問題を引き起こす可能性があることを実現します。 あなたのデザイン、言語、あなたが選択したプラットフォーム(例えば、C ++で書かれていたシステムより悪い行う可能性があるJavaやC#などのガベージコレクションベースの言語で書かれたシステム)に依存もちろん。

私はリアルタイムシステムでは、手続き型プログラミングがより適切かもしれないと思います。

OOPであることを主張しませすべてのプロジェクトが実際のOOPであることに注意してください。時には、コードの大半は手続きである、またはデータ・モデルは、その上の貧血のである、と。 ..

ZYX、あなたは "システムのほとんどは、リレーショナルデータベースを使用して..."、書いた

私はそのような事はありません怖いです。リレーショナルモデルは来年40歳になりますと、まだ実装されていません。私は、あなたが意味を考える「SQLデータベース。」あなたは、リレーショナルDBMSとSQL DBMSの違いを理解するためにファビアン・パスカルで何かを読む必要があります。

「...リレーショナルモデルは通常、原因その人気に選択されています」

Trueの場合、それが人気です。

"...ツールの可用性、"

残念ながら、必要な主工具なし:リレーショナル・モデルの実装

"サポート"

うん、リレーショナルモデルは細かいサポートを持って、私は確信しているが、それは、DBMSの実装によって完全にサポートされていないのです。

「とリレーショナルモデルは、実際には数学的な概念であるという事実」

はい、それは数学的な考え方だが、実装されていない、それは象牙の塔に大幅に制限されます。弦理論は数学的概念ですが、私はそれを使用してシステムを実装していないでしょう。

それは反証可能であること:それはすべての科学の最初の要件を欠いているため、

実際には、それはmethematical概念であることだにも関わらず、それは(コンピュータサイエンスのように)確かに科学ではない、私たちに対するリレーショナルDBMSのない実装ではありませんその主張を確認することができます。

これは、純粋な蛇油です。

"... OOPに反する。"

そして、OOPに反して、リレーショナルモデルが実装されていない。

SQLの本を購入し、生産性を得る。

非生産的な理論家にリレーショナルモデルのままにしておきます。

見る これ そして これ. 。どうやら、C# は 5 つの異なるプログラミング パラダイムで使用でき、C++ は 3 つの異なるプログラミング パラダイムで使用できるようです。

ソフトウェア構築は基礎物理学とは似ていません。物理学は、新しい実験データや理論によって挑戦される可能性のあるパラダイムを使用して現実を記述しようと努めています。物理学は、ソフトウェア構築とは異なり、「真実」を探求する科学です。

ソフトウェア構築というのは、 仕事. 。あなたはそうする必要があります 生産的な, 、つまり誰かがお金を払って何らかの目標を達成すること。パラダイムが使用されるのは、それが役立つからです。 ソフトウェアを効率的に作成する. 。全員が同意する必要はありません。OOP を実行してそれがうまく機能しているのであれば、それを学び、後でソフトウェア構造全体を再考する時間とお金があれば、「新しい」パラダイムが私にとって 20% 役立つ可能性があるかどうかは気にしません。私はそれを一から再設計して取り組んでいます。

また、あなたが別のパラダイムを使用しているかもしれませんが、私は日本食レストランを経営してお金を稼ぐことができ、あなたは隣のメキシコ料理レストランを経営してお金を稼ぐことができるのと同じように、私はまだ幸せです。日本食がメキシコ料理よりも優れているかどうかをあなたと議論する必要はありません。

OOP がすぐになくなるとは思えませんが、OOP は私たちの問題やメンタル モデルにあまりにもよく当てはまります。

しかし、私たちが目にし始めているのは、宣言的かつ機能的なアイデアがオブジェクト指向設計に組み込まれた、マルチパラダイムのアプローチです。新しい JVM 言語のほとんど (JavaFX、Scala、Clojure など) や .net プラットフォームの LINQ や F# がこの好例です。

ここで私が話しているのは OO の置き換えではなく、それを補完することであることに注意することが重要です。

  • Javafxは、宣言的なソリューションがSQLとXSLTを超えていることを示しており、GUIの視覚コンポーネント間の結合特性とイベントにも使用できることを示しました。

  • フォールトトレラントで非常に同時のシステムの場合、機能プログラミングは とても Ericsson AXD301(Erlangを使用してプログラムされた)によって示されているように、良いフィット

それで...同時実行性がより重要になり、FP の人気が高まるにつれて、このパラダイムをサポートしていない言語は苦しむことになると思います。これには、C++、Java、Ruby など、現在人気のある多くのものが含まれますが、JavaScript は非常にうまく対応できるはずです。

を使用OOPは(新しい機能を追加/変更/更新のように)し、理解を管理するためのコードが容易になります。これは大きなプロジェクトでは特にそうです。モジュール/オブジェクトがそのデータに自分のデータと操作をカプセル化しているので、それは機能性と大きな画像を理解する方が簡単です。

はOOPの利点は、次いで「ファイルにデータをダンプする方法のグループ」を記述する、特定の機能を包含しその各々のLogManagerまたはOrderManager、および(他の開発者/管理/顧客に)議論することが容易であることです「注文の詳細を追跡する方法」ます。

私はOOPは、特に大規模なプロジェクトで便利ですが、そう評価し、将来的に新しいものに目を光らせておくと便利です何保つ上げ、新たな概念が常に存在していると思いますので。

人は「オブジェクト」として様々なものを考えると、それらを分類するのが好きなので、OOPはとても人気であることは間違いありません。しかし、OOPは大きな人気を得ていないいくつかの領域があります。システムのほとんどは、リレーショナルデータベースではなく、目的を使用しています。第二のものは、いくつかの注目すべきレコードを保持し、タスクの種類によっては優れている場合でも、リレーショナルモデルはunsually、その人気、ツールの利用可能性、サポート、リレーショナルモデルはに反して、実際には数学的な概念であるという事実に選ばれますOOPます。

私はOOPを見たことがない別の領域は、ソフトウェア構築プロセスです。すべての設定とスクリプトはOOPは、このようなタスクのためには複雑すぎる部分的にので、部分的理由シェル言語のOOPのサポートの不足のため、手続きされていることを確認します。

私からの少し物議を醸す意見ですが、少なくとも現在一般的に適用されている種類の OOP は、そうではないと思います。 それ 私の特定の分野で最大規模のソフトウェア (VFX、シーンの構成やアプリケーションの状態がゲームと似ている) を作成するのに役立ちます。中規模から小規模では非常に便利だと思います。過去に何人かの暴徒を招待したことがあるので、ここでは少し注意する必要がありますが、これは私の特定の種類のドメインにおける私の狭い経験の中でのことであると認めるべきです。

私がよく感じる難しさは、データをカプセル化するこれらの小さな具体的なオブジェクトがある場合、それらが互いに通信しようとすることです。それらの間の相互作用は、次のように非常に複雑になる可能性があります (数千のオブジェクトにわたる実際のアプリケーションではさらに複雑になる場合を除きます)。

enter image description here

そして、これは結合に直接関係する依存関係グラフではなく、「相互作用グラフ」です。これらの具体的なオブジェクトを相互に分離するための抽象化が存在する可能性があります。 Foo 話さないかもしれない Bar 直接。代わりにそれを通して話しかける可能性があります IBar またはこの種のもの。このグラフはまだ接続できます FooBar なぜなら、切り離されているとはいえ、彼らはまだお互いに話しているからです。

そして、独自の小さなエコシステムを構成する中小規模のオブジェクト間のこのすべての通信を、私のドメイン内の大規模なコードベース全体に適用すると、維持することが非常に困難になる可能性があります。そして、副作用などに関して、オブジェクト間のこれらすべての相互作用で何が起こるかを推論するのが難しいため、保守が非常に困難になります。

代わりに、私が便利だと感じたのは、コードベース全体を、中央の「データベース」にアクセスする完全に独立した大規模なサブシステムに編成することです。その後、各サブシステムがデータの入出力を行います。他のいくつかのサブシステムは同じデータにアクセスする可能性がありますが、1 つのシステムが相互に直接通信することはありません。

enter image description here

...またはこれ:

enter image description here

...そして、個々のシステムは状態をカプセル化しようとしなくなりました。独自のエコシステムになろうとはしません。代わりに、中央データベースでデータの読み取りと書き込みを行います。

もちろん、各サブシステムの実装では、実装を支援するために多数のオブジェクトが使用される場合があります。そして、私が OOP が非常に役立つと思うのは、これらのサブシステムの実装においてです。しかし、これらの各サブシステムは、大きすぎず、比較的中規模から小規模のプロジェクトを構成しており、OOP が非常に役立つと私が感じるのは、その中規模から小規模のプロジェクトです。

最低限の知識で学べる「流れ作業プログラミング」

これにより、各サブシステムは、外の世界で何が起こっているかについてほとんど知識を持たずに、自分の仕事の実行だけに集中することができます。物理学に焦点を当てている開発者は、物理サブシステムに座って、ソフトウェアがどのように動作するかについてほとんど知りません。ただし、そこからモーション コンポーネント (単なるデータ) などを取得し、そのデータに物理学を適用して変換できる中央データベースがあることを除きます。そのため、彼の仕事は非常にシンプルになり、他のすべてがどのように機能するかに関する最小限の知識を持って、自分の最も得意なことを行うことができます。中央データを入力し、中央データを出力します。他のすべてが機能するためには、各サブシステムが正しく行う必要があるのはこれだけです。これは、私が私の分野で見つけた「組立ライン プログラミング」に最も近いもので、各開発者がシステム全体がどのように機能するかに関する最小限の知識を持って作業を行うことができます。

各サブシステムの焦点が狭いため、テストも非常に簡単です。私たちは依存関係注入で具体的なオブジェクトをモックするのではなく、特定のシステムに関連する最小限のデータを生成し、特定のシステムが特定の入力に対して正しい出力を提供するかどうかをテストするだけです。テストするシステムが非常に少ないため (複雑なソフトウェアを構成できるシステムは数十個だけです)、必要なテストの数も大幅に削減されます。

カプセル化の解除

その後、システムは、実質的に互いの存在を意識しない独立したサブシステムを通じて中央アプリケーションの状態を変換するかなりフラットなパイプラインに変わります。別のシステムが処理するデータベースに中央イベントをプッシュすることがありますが、その別のシステムはそのイベントがどこから来たのかをまだ認識していません。これが、少なくとも私の領域では複雑さに取り組むための鍵であり、効果的にはエンティティ コンポーネント システムを介して行われることがわかりました。

しかし、これを達成し、システムが各サブシステムと通信する必要を避けるためにカプセル化を解除しているため、これらすべてのサブシステムを切り離し、外界についての最小限の知識で動作させることは、大規模な手続き型または関数型プログラミングに近いものに似ています。他の。ズームインすると、これらのサブシステムのいずれかを実装するために使用されているオブジェクトの割合が見つかるかもしれませんが、最も広いスケールで見ると、システムは OOP 以外のものに似ています。

グローバルデータ

正直に言うと、最初は ECS を自分の分野のアーキテクチャ設計に適用することに非常に躊躇していました。その理由は、第一に、私の知る限りでは、人気のある商用競合他社 (3DS Max、SoftImage など) ではこれまで ECS が行われていなかったこと、そして第二に、ECS を適用したことがなかったことです。 、グローバルにアクセス可能なデータの塊のように見えます。

ただし、これは大きな問題ではないことがわかりました。私たちは依然として非常に効果的に不変条件を維持することができ、おそらく以前よりもさらに改善されています。その理由は、ECS がすべてをシステムとコンポーネントに編成する方法にあります。オーディオ システムは、たとえば最も不正な状況下であっても、モーション コンポーネントを変更しようとしないので安心してください。たとえ連携が不十分なチームであっても、ECS がどのシステムがどのコンポーネントにアクセスするかを推論できない状態にまで劣化する可能性は非常に低いです。これは紙の上ではかなり明白であり、特定のシステムがアクセスする理由が事実上まったくないためです。不適切なコンポーネント。

それどころか、緩い調整とクランチタイムの下で以前のコードベースで行われた多くのハッキングな行為は、抽象化をX線で急いで試みて行われたため、データが広く公開され、ハッキングな行為に対する以前の誘惑の多くが取り除かれることがよくありました。オブジェクトのエコシステムの内部にアクセスします。人々がアクセスしたいデータを急いで取得して操作しようとした結果、抽象化が漏洩し始めました。彼らは基本的に、ただデータにアクセスしようとしてフープを飛び越えていたため、インターフェイスのデザインがすぐに劣化してしまいました。

特定の種類のコンポーネントを変更するシステムが 1 つだけ (例外的なケースでは 2 つ) しかないことが多いため、システムの編成方法によっては、カプセル化に漠然と似たものがまだ存在します。しかし、彼らはそのデータを所有しておらず、そのデータを取得する機能も提供していません。システムは相互に通信しません。これらはすべて、中央の ECS データベースを通じて動作します (これは、これらすべてのシステムに注入する必要がある唯一の依存関係です)。

柔軟性と拡張性

これはすでにエンティティコンポーネントシステムに関する外部リソースで広く議論されていますが、哺乳類、昆虫、植物であるクリーチャーの提案のように、後知恵で根本的に新しいデザインのアイデアを適応させるのに非常に柔軟です。芽は一度に日光の下で去ります。

理由の 1 つは、破るべき中心的な抽象概念がないためです。さらに多くのデータが必要な場合、または植物、哺乳類、昆虫に必要なコンポーネントをつなぎ合わせたエンティティを作成するだけの場合は、新しいコンポーネントをいくつか導入します。昆虫、哺乳類、植物のコンポーネントを処理するように設計されたシステムは、それを自動的に取得するため、新しいコンポーネントの組み合わせでエンティティをインスタンス化するコード行を追加する以外は何も変更せずに、必要な動作を得ることができます。まったく新しい機能が必要な場合は、新しいシステムを追加するか、既存のシステムを変更するだけです。

他であまり議論されていないのは、予期できなかった概念を打ち破る設計変更がないシナリオでも、これによってメンテナンスがどれほど容易になるかということです。ECS の柔軟性を無視したとしても、コードベースが一定の規模に達すると、ECS によって作業が大幅に簡素化されます。

オブジェクトをデータに変える

以前の OOP の多いコードベースでは、上記の最初のグラフに近いコードベースを維持するのが難しいことがわかりましたが、必要なコードの量が爆発的に増加しました。 Car この図では:

enter image description here

...複数のインターフェイスを実装する完全に別個のサブタイプ (クラス) として構築する必要がありました。そのため、システム内には爆発的な数のオブジェクトが存在しました。ディレクショナル ライトからのポイント ライトの別のオブジェクト、別の魚眼カメラの別のオブジェクトなど。無限の組み合わせで数十の抽象インターフェイスを実装する何千ものオブジェクトがありました。

ECS と比較すると、必要なのはわずか数百で、コードのごく一部を使用する前にまったく同じことを行うことができました。 Car エンティティをそのクラスを必要としない何かに変換します。これは、1 つのコンポーネント データの一般化されたインスタンスとしての単純なコンポーネント データのコレクションに変わります。 Entity タイプ。

OOP の代替手段

したがって、このようなケースでは、設計の最も広範なレベルで OOP が過剰に適用されると、保守性が実際に低下し始める可能性があります。システムを最も広い鳥瞰図で見ると、オブジェクトがオブジェクトと相互作用し、オブジェクトがオブジェクトと相互作用するという、それほど「深く」モデル化しようとせずに、抽象的であってもフラット化することが役立ちます。

私が過去に取り組んだ 2 つのシステムと現在を比較すると、新しいシステムの方が機能は多くなりますが、数十万の LOC が必要です。前者には 2,000 万以上の LOC が必要でした。もちろん、前者には膨大なレガシーがあったため、これは最も公平な比較ではありませんが、レガシーの荷物がなければ機能的にまったく同等である (少なくともほぼ同等に近い) 2 つのシステムの一部を切り取ってみると、 ECS は、同じことを行うためにコードのごく一部を使用します。その理由の 1 つは、クラスを生データ (コンポーネント) のコレクション (エンティティ) に変換し、代わりにそれらを処理する大規模なシステムを使用することで、システム内に存在するクラスの数を劇的に減らすためです。小型/中型の物体を船に積み込んだ状態。

真に非純粋なパラダイムが実際に大規模なソリューションに適した選択肢であるシナリオはありますか?それとも、最近は前代未聞ですか?

それは決して前代未聞のことではありません。たとえば、上で説明したシステムはゲームで広く使用されています。私の分野ではこれは非常にまれなことですが (私の分野のアーキテクチャのほとんどは純粋なインターフェイスを備えた COM のようなもので、私が過去に取り組んだのはこのタイプのアーキテクチャです)、ゲーマーがいつ何をしているかをじっと観察すると、アーキテクチャを設計することで、成長してもなお非常に理解しやすいものを作成できるという点で、大きな違いが生まれました。

そうは言っても、ECS をそれ自体がオブジェクト指向プログラミングの一種であると考える人もいます。もしそうなら、それはデータ (コンポーネントとそれらを構成するエンティティ) と機能 (システム) が分離されているため、ほとんどの人が考える種類の OOP とは似ていません。これには、OOP の最も基本的な側面の 1 つと考えられる、広範なシステム レベルでのカプセル化を放棄する必要があります。

高レベルのコーディング

しかし、通常、より高いレベルのソリューションの断片は、ほとんどの場合OOPファッションでまとめられているように思えます。

非常に高レベルのコードを使用してアプリケーションを組み立てることができれば、チームが保守しなければならないコードに関しては小規模または中程度の規模になる傾向があり、おそらく OOP を使用して非常に効率的に組み立てることができます。

私の分野の VFX では、レイトレーシング、画像処理、メッシュ処理、流体力学などの比較的低レベルの処理を行う必要があることが多く、実際に競合しているため、これらをサードパーティ製品から単につなぎ合わせることができません。低レベルで何ができるかという点で重要です (ユーザーは、たとえば、優れた GUI よりも、最先端の競争力のあるプロダクション レンダリングの改善に興奮しています)。そのため、ビットやバイトの非常に低レベルのシャッフルから、スクリプト作成者が埋め込みスクリプト言語を通じて作成する非常に高レベルのコードに至るまで、非常に多くのコードが存在する可能性があります。

コミュニケーションのインターウェブ

しかし、高レベル、低レベル、またはコンボのいずれのタイプのアプリケーションでも、非常に複雑な中央アプリケーションの状態を中心に展開する、十分に大きな規模のポイントがあり、すべてをカプセル化しようとするのはもはや役に立たないことがわかりました。オブジェクトに。そうすることで、あらゆるものの間で発生する相互作用の量が増大するため、複雑さが増大し、何が起こっているのかを推論することが困難になる傾向があります。十分な規模で、相互に通信する必要があるカプセル化されたエコシステムとしてそれぞれをモデル化するのをやめる限界点がなければ、何千ものエコシステムが相互に通信していることを推論するのは、もはやそれほど簡単ではなくなります。それぞれが個別に単純であっても、全体として取り込むすべてのものは心を圧倒し始める可能性があり、変更を加えたり、新しい機能を追加したり、物事をデバッグしたりするために、多くのことを取り込まなければならないことがよくあります。 OOP 原則のみを中心に大規模システム全体の設計を回転させようとします。少なくとも一部のドメインでは、ある程度の規模でカプセル化を解除するのに役立ちます。

その時点では、たとえば、物理システムにそれ自身のデータをカプセル化させることは、必ずしもそれほど有用ではなくなります (そうしないと、多くのものが物理システムと通信してそのデータを取得したり、適切な入力データで初期化したりする可能性があります)。 ECS によるこの代替手段は非常に役立つと感じました。なぜなら、これはアナロジカル物理システムやそのような巨大なシステムすべてを、相互に意識することができる「中央データベース トランスフォーマー」または「何か新しいものを出力する中央データベース リーダー」に変えるからです。その後、各システムは、非常に複雑な通信グラフのノードを形成するオブジェクトというよりも、フラットなパイプライン内のプロセスに似てきます。

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