41

[編集:]以前、私はこれを、OOPを使用する場合と手続き型プログラミングを使用する場合について、おそらくフレームが不十分な質問として質問しました。一部の回答は、OOPの理解に役立つことを求めていたことを意味します。それどころか、私はOOPをよく使用しましたが、手続き型アプローチをいつ使用するかを知りたいと思います。回答から判断すると、OOPは通常、より優れたオールラウンドなアプローチであるが、OOPアーキテクチャが長期的に再利用のメリットをもたらさない場合は、手続き型言語を使用する必要があるというかなり強いコンセンサスがあると思います。

しかし、Javaプログラマーとしての私の経験はそうではありませんでした。私が設計した大規模なJavaプログラムは、私が作成したコードの1/10で、Perlの第一人者によって書き直され、OOPの完全性のモデルと同じくらい堅牢に見えました。私のアーキテクチャでは、かなりの量の再利用が見られましたが、より簡潔な手続き型アプローチによって優れたソリューションが生み出されました。

ですから、繰り返しになるリスクを冒して、オブジェクト指向のアプローチではなく、どのような状況で手続き型を選択すべきか疑問に思っています。OOPアーキテクチャが行き過ぎであり、手続き型アプローチがより簡潔で効率的である可能性が高い状況を事前にどのように特定しますか。

誰かがそれらのシナリオがどのように見えるかの例を提案できますか?

手続き型プログラミングアプローチによってより適切に提供されるプロジェクトを事前に特定するための良い方法は何ですか?

4

23 に答える 23

44

再利用に関しては、 Glass の3 のルールが気に入っています (これはあなたが興味を持っているようです)。

1) 再利用可能なコンポーネントを構築するのは、使い捨てのコンポーネントよりも 3 倍難しい
2) 再利用可能なコンポーネントは、再利用ライブラリに受け入れられるほど十分に一般的になる前に、3 つの異なるアプリケーションで試してみる必要があります。

これから、これらの結果を推定できると思います

a) 使い捨てのコンポーネントを構築するのにかかる時間の 3 倍の予算がない場合は、再利用を延期する必要があります。(難易度 = 時間と仮定)
b) 構築しているコンポーネントを使用する場所が 3 つない場合は、再利用可能なコンポーネントの構築を延期する必要があります。

OOP は使い捨てコンポーネントを構築するのに役立つと今でも思っています。後で本当に再利用可能なものにいつでもリファクタリングできるからです。(PP から OOP にリファクタリングすることもできますが、OOP には組織とカプセル化に関して十分なメリットがあると思います)

于 2009-02-09T14:14:15.747 に答える
18

再利用性 (または再利用性の欠如) は、特定のプログラミング パラダイムに限定されません。必要に応じて、オブジェクト指向、手続き型、関数型、またはその他のプログラミングを使用します。組織化と再利用性は、ツールではなく、何をするかによってもたらされます。

于 2009-02-09T14:12:19.620 に答える
15

ご自身で答えを出してください。大規模なプロジェクトでは、面倒になりすぎないように OOP が必要なだけです。

私の見解では、OOP の最大の利点はコードの編成です。これには、DRY とカプセル化の原則が含まれます。

于 2009-02-09T14:10:57.003 に答える
15

OOP を宗教的に支持する人は、これらのコメントにも見られるように、支持を正当化する事実を持っていません。彼らは大学で OOP と OOP のみを使用して賞賛するように訓練されている (または洗脳されている) ため、盲目的に OOP をサポートしています。彼らは PP で実際の作業を行ったことがありますか? チーム環境で不注意なプログラマーからコードを保護することを除けば、OOP はあまり役に立ちません。PP と OOP の両方で何年も個人的に働いてきた私は、PP がシンプルで、単純明快で、より効率的であることを知り、次の賢明な男性と女性に同意します。

(参照: http://en.wikipedia.org/wiki/Object-directional_programming ):

多くの著名な研究者やプログラマーが OOP を批判しています。以下は不完全なリストです。

  • Luca Cardelli は、「<a href="http://lucacardelli.name/Papers/BadPropertiesOfOO.html" rel="noreferrer">オブジェクト指向言語の悪いエンジニアリング プロパティ」というタイトルの論文を書きました。

  • Richard Stallman は 1995 年に次のように書いています。私は Lisp Machine ウィンドウ システムで作業するときに OOP を使用しましたが、それが優れたプログラミング方法であるという一般的な見方には同意しません。」</p>

  • Potok らによる研究。は、OOP と手続き型アプローチの間で生産性に大きな違いがないことを示しています。

  • Christopher J. Date は、OOP の厳密な定義が合意に達していないため、OOP を他の技術、特にリレーショナル技術と批判的に比較することは難しいと述べました。RDBMSをサポートするための一種のカスタマイズ可能な型システムとしてOOPを使用するOOPの理論的基礎が提案されています。

  • アレクサンダー・ステパノフは、OOP は数学的に制限された視点を提供することを示唆し、「人工知能とほぼ同じくらいのでっち上げ」と呼びました (おそらく、1980 年代の人工知能プロジェクトとマーケティングは、振り返ってみると熱心すぎると見なされることがあります)。

  • Paul Graham は、OOP の目的は、平凡な組織の平凡なプログラマーが「あまりにも多くの損害を与える」ことを防ぐ「群集メカニズム」として機能することであると示唆しています。これは、より強力でコンパクトな手法を使用する方法を知っている生産的なプログラマーの作業を遅らせるという犠牲を払っています。

  • Erlang の主な発明者である Joe Armstrong は、次のように述べています。バナナが欲しかったのに、手に入れたのはバナナとジャングル全体を持ったゴリラでした。」</p>

  • COMPUTE! の著者で元編集者の Richard Mansfield 氏 雑誌は、「長年にわたる無数の他の知的流行(「関連性」、共産主義、「モダニズム」など、歴史にはそれらが散らばっています)と同様に、最終的に現実が主張するまで、OOPは私たちと共にあります. しかし、OOP が現在大学と職場の両方にどのように浸透しているかを考えると、OOP は永続的な妄想であることが証明される可能性があります。教化されたプログラマーの全世代がアカデミーから行進し続け、残りの人生を OOP に専念し、OOP 以外の何物でもない.」また、「OOP はプログラムを作成することであり、空港のセキュリティを通過することは飛行することです」と言われています。

于 2010-08-19T14:58:13.890 に答える
13

任意の問題に対して見つけることができる最も簡潔で標準ベースのアプローチを使用することをお勧めします。Perl を使用したあなたの同僚は、特定のツールをよく知っている優秀な開発者は、方法論に関係なく素晴らしい結果を達成できることを示しました。Java 対 Perl のプロジェクトを手続き型対 OOP の議論の良い例として比較するのではなく、Perl と同様に簡潔な言語 (Ruby など) との対決を見たいと思います。オブジェクト指向の。今、それは私が見たいものです。私の推測では、Ruby がトップになると思いますが、ここで言語の炎上戦争を引き起こすことには興味がありません。私が言いたいのは、仕事に適したツールを選択することだけです。どのようなアプローチでも、最も効率的で堅牢な方法でタスクを達成できます。可能な方法。

于 2009-02-09T22:31:35.690 に答える
6

少しアジャイルを組み合わせた DRY 原則 (Don't Repeat Yourself) は良いアプローチだと思います。機能する最も単純なものから始めて段階的にプログラムを構築し、次に機能を 1 つずつ追加し、必要に応じてコードをリファクタリングします。

同じ数行のコードを何度も書いていることに気付いた場合 (データが異なる可能性があります)、変更されたものと変更されていないものを分離するのに役立つ抽象化について考える時が来ました。

自信を持ってリファクタリングできるように、反復ごとに徹底的な単体テストを作成します。

コードのどの部分を再利用可能にする必要があるかを予測するのに時間をかけすぎるのは誤りです。システムのサイズが大きくなり始めると、すぐに明らかになります。

複数の同時開発チームによる大規模なプロジェクトでは、開発を導くための何らかのアーキテクチャ計画が必要ですが、自分自身または小規模な協力チームで作業している場合は、DRY 原則に固執すればアーキテクチャが自然に浮かび上がります。

このアプローチのもう 1 つの利点は、何をするにしても実世界の経験に基づいていることです。私のお気に入りのアナロジーは、建物がどのように建設されるかを想像する前に、レンガで遊ぶ必要があるということです。

于 2009-02-09T14:48:13.543 に答える
6

非常に明確に特定された問題があり、仕様が変更されず非常に高速に実行されるプログラムが必要な場合は、手続き型スタイルを使用する必要があると思います。この場合、保守性とパフォーマンスを交換することができます。

これは通常、ゲーム エンジン科学シミュレーション プログラムを作成する場合に当てはまります。プログラムが 1 秒間に 100 万回以上計算する場合は、最適化する必要があります。

非常に効率的なアルゴリズムを使用できますが、キャッシュの使用を最適化するまで十分に高速ではありません。データがキャッシュされると、パフォーマンスが大幅に向上する可能性があります。これは、CPU が RAM からバイトをフェッチする必要がないことを意味します。これを実現するには、データを互いに近くに格納するようにし、実行可能ファイルとデータのサイズを最小限に抑え、できるだけ少ないポインタを使用するようにしてください (余裕がある場合は、静的なグローバル固定サイズの配列を使用してください)。

ポインターを使用すると、メモリ内で継続的にジャンプし、CPU は毎回キャッシュをリロードする必要があります。OOP コードはポインターでいっぱいです。すべてのオブジェクトは、そのメモリ アドレスによって格納されます。あなたが呼ぶnewオブジェクトをメモリ全体に分散させると、キャッシュの最適化がほとんど不可能になります(アロケーターまたはガベージコレクターを使用しない限り、物事を互いに近づけることはできません)。コールバックと仮想関数を呼び出します。通常、コンパイラは仮想関数をインライン化できず、仮想関数の呼び出しは比較的低速です (VMT にジャンプし、仮想関数のアドレスを取得して呼び出します [これには、パラメーターとローカル変数をスタックにプッシュし、関数を実行することが含まれます)。次に、すべてをポップします])。毎秒 0 から 1000000 まで 25 回ループを実行する場合、これは非常に重要です。手続き型スタイルを使用することにより、仮想関数がなくなり、オプティマイザはそれらのホット ループ内のすべてをインライン化できます。

于 2010-08-02T08:10:46.710 に答える
5

「オブジェクト指向言語の問題は、暗黙の環境を持ち歩いていることです。バナナが欲しかったのに、バナナとジャングル全体を持ったゴリラが手に入ったのです。」—ジョー・アームストロング

ジャングルが欲しいですか?

于 2010-08-19T15:06:34.363 に答える
4

手続き型プログラムは、特定の種類のプログラムではより単純になる場合があります。通常、これらは短いスクリプトのようなプログラムです。

于 2009-02-09T22:39:33.487 に答える
3

2つの概念は相互に排他的ではありません。PPをOOPと組み合わせて使用​​する可能性が非常に高く、それらを分離する方法がわかりません。

于 2009-02-09T14:03:53.027 に答える
3

次のシナリオを考えてみましょう: あなたのコードは OO ではありません。データ構造と、データ構造を操作するプログラム全体の多くの関数があります。各関数はデータ構造をパラメーターとして取り、データ構造の「data_type」フィールドに応じてさまざまなことを行います。

すべてが機能しており、変更される予定がない場合、それが OO であるかどうかは誰が気にしますか? それは働いています。終わった。手続き的により速く書くことができれば、おそらくそれが道です。

しかし、それが変更されることはないと確信していますか? 新しいタイプのデータ構造を追加する可能性が高いとしましょう。これらの関数で操作する新しいデータ構造型を追加するたびに、それらの関数をすべて見つけて変更し、新しい「else if」ケースを追加して、必要な動作を確認して追加する必要があります。新しいタイプのデータ構造に影響を与えます。プログラムが大きく複雑になるほど、この問題は大きくなります。この可能性が高いほど、OO アプローチを使用する方が適切です。

そして - バグなく動作していると確信していますか? 複雑なスイッチング ロジックは、コードの各ユニットのテストをより複雑にします。ポリモーフィックなメソッド呼び出しでは、言語が切り替えロジックを処理し、各メソッドをよりシンプルかつ簡単にテストできます。

于 2009-06-10T15:28:09.743 に答える
2

OOP の目標の 1 つは、再利用を容易にすることでしたが、それだけが目的ではありません。オブジェクトを効果的に使用するための鍵は、デザイン パターンです。

私たちは皆、さまざまな手順とデータ構造を組み合わせて共通のタスクを実行する方法を教えてくれるアルゴリズムの考え方に慣れています。逆に、オブジェクトを組み合わせて一般的なタスクを実行する方法については、ギャング オブ フォーによるデザイン パターンを参照してください。

デザイン パターンについて学ぶ前は、オブジェクトをスーパー タイプ構造体として以外に効果的に使用する方法についてほとんど理解していませんでした。

インターフェイスの実装は、継承よりも重要ではないにしても、同じくらい重要であることを忘れないでください。当時、C++ はオブジェクト指向プログラミングの主要な例であり、インターフェイスの使用は継承 (仮想関数など) に比べてわかりにくいものでした。C++ レガシは、さまざまなチュートリアルや広範な概要で動作を再利用することに重点が置かれることを意味しました。それ以来、Java、C#、およびその他の言語は、インターフェースをより重視するようになりました。

インターフェイスが優れているのは、2 つのオブジェクトがそれぞれとどのように相互作用するかを正確に定義することです。動作を再利用することではありません。結局のところ、私たちのソフトウェアの多くは、さまざまな部分がどのように相互作用するかに関するものです。したがって、インターフェイスを使用すると、再利用可能なコンポーネントを作成するよりもはるかに生産性が向上します。

他の多くのプログラミングのアイデアと同様に、オブジェクトはツールであることを忘れないでください。それらがあなたのプロジェクトにどれだけうまく機能するかについては、あなたの最善の判断を下す必要があります. 私の金属切断機用の CAD/CAM ソフトウェアには、オブジェクトに配置する理由がないため、オブジェクトに配置されていない重要な数学関数があります。代わりに、それらはライブラリから公開され、それらを必要とするオブジェクトによって使用されます。次に、構造が自然にこのセットアップにつながるため、オブジェクト指向にされた数学関数がいくつかあります。(ポイントのリストを取得し、いくつかの異なるタイプのカット パスに変換します)。繰り返しますが、最善の判断を下してください。

于 2009-02-09T14:36:02.527 に答える
2

Grady Booch は、10000 行以上のコードで OOP から本当に多くの恩恵を受け始めると言ったことがあります。

ただし、私は常にOOの方法を使用します。200行でも。これは長期的には優れたアプローチであり、オーバーヘッドは過大評価されている言い訳にすぎません。大きなことはすべて小さなことから始まります。

于 2009-02-09T14:20:31.317 に答える
1

私は常にトップダウン方式で設計を開始します。トップ パーツでは、OOP の観点から考える方がはるかに簡単です。しかし、いくつかの小さな特定の部分をコーディングするときが来ると、プロシージャー・プログラミングだけで生産性が大幅に向上します。OOP は、プロジェクトの設計と形成において優れているため、分割と支配のパラダイムを適用できます。しかし、それは宗教であったため、コードのすべての側面に適用することはできません:)

于 2009-02-09T14:36:39.873 に答える
0

私見ですが、OOP の長期的な利点は、短期的に節約できる時間よりも重要です。

AZが言ったように、手続き型の方法でOOPを使用することは(私はかなりやっています)、(小規模なプロジェクトの場合)良い方法です。プロジェクトが大きくなればなるほど、より多くの OOP を採用する必要があります。

于 2009-02-09T15:23:33.927 に答える
0

両方の概念で悪いソフトウェアを作成できます。それでも、複雑なソフトウェアは、手続き型言語よりもオブジェクト指向言語で作成、理解、保守する方がはるかに簡単です。非常に複雑な ERP アプリケーションを手続き型言語 (Oracle PL/SQL) で作成し、その後 OOP (C#) に切り替えました。昔も今も新鮮な空気の息吹です。

于 2015-04-28T10:49:06.417 に答える
-1

ほとんどの研究で、オブジェクト指向コードは手続き型コードよりも簡潔であることがわかっています。既存の C コードを C++ で書き直したプロジェクトを見ると (私が必ずしもアドバイスするものではありませんが)、通常、コード サイズが 50 ~ 75% 削減されていることがわかります。

答えは、常に OO を使用することです。

于 2009-02-09T14:10:29.093 に答える