オブジェクト指向プログラミングの勉強を始めてから、関数が優れている、またはすべての問題をオブジェクトとしてモデル化する必要があるとは限らないという記事やブログをよく読んでいます。あなたの個人的なプログラミングの冒険から、問題がOOPによってよりよく解決されるのはいつだと思いますか?
16 に答える
厳格なルールはありません。問題を解決し、オブジェクト指向の考え方で考えるのが得意な場合、問題は OOP でより適切に解決されます。オブジェクト指向は、コンピューティングを問題解決のためのより優れたツールにしようとする試みから生まれたツールの 1 つです。
ただし、これによりコードの再利用が向上し、よりきれいなコードにつながる可能性もあります。しかし、これらの高く評価されている資質は、実際にはほとんど価値がないことがよくあります。OO 手法を既存の機能アプリケーションに適用すると、実際には多くの問題が発生する可能性があります。スキルは、さまざまなテクニックを学び、目前の問題に最も適したものを適用することにあります。
OO は、ソフトウェア開発に対する涅槃のようなソリューションとしてよく引用されますが、目前の問題に適用するのが適切でない場合が多くあります。多くの場合、それが実際には必要ない場合でも、完璧なソリューションに到達するために問題を過度に設計することにつながる可能性があります。
本質的に、OOP は実際にはオブジェクト指向プログラミングではなく、オブジェクト指向思考をオブジェクト指向テクニックをサポートできるプログラミング言語にマッピングしたものです。OO 手法は、本質的に OO ではない言語でもサポートできます。また、関数型言語内で使用して利点を活用できる手法があります。
例として、私は約 20 年間オブジェクト指向ソフトウェアを開発してきたので、問題を解決するときに、作成している言語に関係なく、オブジェクト指向の用語で考える傾向があります。現在、私は Perl 5.6 を使用してポリモーフィズムを実装しています。それをサポートします。コードのメンテナンスと拡張を開発の問題ではなく単純な構成タスクにするため、これを選択しました。
これが明確かどうかはわかりません。OO コートで難しい人もいれば、Functional Court で難しい人もいます。そして、両方を試し、それぞれの長所を活かそうとする人もいます。どちらも完璧ではありませんが、言語に関係なく利用できる非常に優れた特徴があります。
OOP を学習しようとしている場合は、OOP だけに集中するのではなく、オブジェクト指向分析と一般的な OO 原則を問題解決の全領域に活用するようにしてください。
私は古いタイマーですが、長い間OOPもプログラムしてきました。私は個人的に、OOPを使用するためだけに使用することに反対しています。私は、オブジェクトが存在する特定の理由を持ち、具体的なものをモデル化し、意味をなすものを好みます。
私が多くの新しい開発者に抱えている問題は、彼らが作成するコードで消費しているリソースの概念がないことです。大量のデータを処理してデータベースにアクセスする場合、「完璧な」オブジェクトモデルは、パフォーマンスとリソースに対して実行できる最悪の事態になる可能性があります。
私の結論は、オブジェクトモデルの実装によるパフォーマンス/リソースへの影響を考慮している限り、オブジェクトとして意味がある場合は、オブジェクトとしてプログラムすることです。
状態およびそれらの状態に対する関連するアクションとまとまりのあるものをモデル化する場合に最適だと思います。それは漠然としたことだと思いますが、ここに完璧な答えがあるかどうかはわかりません。
OOPの特徴は、データと情報をカプセル化して抽象化できることです。これは、大規模なシステムを構築する上での大きなメリットです。他のパラダイムでも同じことができますが、このカテゴリではOOPが特に役立つようです。
また、使用している言語によっても異なります。それが豊富なOOPサポートを備えた言語である場合、おそらくそれを有利に使用する必要があります。そうでない場合は、問題をより小さく、簡単にテストできる部分に分割するのに役立つ他のメカニズムを見つける必要があるかもしれません。
私はOOPに売却されました。
問題の概念を定義できるときはいつでも、オブジェクトにラップすることができます。
OOP の問題は、一部の人々が OOP を使いすぎて、コードをさらに理解しにくくしていることです。オブジェクトに入れるものとサービス (静的クラス) に入れるものに注意すれば、オブジェクトを使用するメリットが得られます。
オブジェクトに属さないものをオブジェクトに入れないでください。最初は考えもしなかった何か新しいことをオブジェクトに実行させ、リファクタリングし、その機能を追加する最良の方法を見つける必要があるからです。
オブジェクトベース、機能的、または手続き型コードよりもオブジェクト指向を優先するかどうかには、5 つの基準があります。これらのスタイルはすべて、すべての言語で利用できることを覚えておいてください。これらはすべて、「この状況では OO を優先すべきか」というスタイルで書かれています。
システムは非常に複雑で、約 9k 以上の LOC (任意のレベル) があります。-- システムが複雑になるにつれて、複雑さをカプセル化することによって得られる利点はかなり大きくなります。オブジェクト指向では、他の手法とは対照的に、複雑さをますますカプセル化する傾向があり、このレベルでは非常に価値があります。この前に、オブジェクト ベースまたは手続き型を優先する必要があります。(これは特定の言語を推奨しているわけではありません。OO C は、私の考えではOO C++ よりもこれらの機能に適合します。OO C++ は、漏れやすい抽象化で悪名高い評判があり、平凡/頑固なプログラマーが 1 人でもランチに店を食べる能力がある言語です)。
あなたのコードはデータに対する操作ではありません (つまり、データベース ベースまたは数学/分析ベース)。データベース ベースのコードは、多くの場合、手続き型スタイルを使用するとより簡単に表現できます。分析ベースのコードは、多くの場合、機能的なスタイルで簡単に表現できます。
モデルは何かのシミュレーションです (OO はシミュレーションに優れています)。
OO のオブジェクト ベースのサブタイプ ディスパッチが価値のあることを行っています (別名、特定のタイプとさまざまなサブタイプのすべてのオブジェクトにメッセージを送信し、それらすべてから適切ではあるが異なる反応を得る必要があります)。 .
特に非ワーカー タスク メソッド タイプのコードベースでは、アプリがマルチスレッド化されていません。OO は、マルチスレッド化され、さまざまなタスクを実行するためにさまざまなスレッドを必要とするプログラムでは非常に問題があります。プログラムが 1 つまたは 2 つのメイン スレッドと同じことを行う多くのワーカー スレッドで構成されている場合、オブジェクト指向プログラムの混乱した制御フローは扱いやすくなります。コードのモノリシック セクション。実際に他のパラダイムを検討してください。Functional はマルチスレッドに優れており (副作用がないことは大きなメリットです)、オブジェクト ベースのプログラミングはオブジェクト指向のカプセル化の一部を利用してメリットをもたらしますが、コードベースの重要なセクションでより追跡可能な手続き型コードを使用できます。もちろん、プロシージャルはこの分野でも優れています。
オブジェクト指向プログラミングを学ぶための鍵は、デザインパターンについて学ぶことです。デザインパターンについて学ぶことで、クラスが必要な場合と必要でない場合をよりよく理解できます。クラスの使用やOOP言語の他の機能のプログラミングで使用される他のものと同様に、設計と要件によって異なります。アルゴリズムのようにデザインパターンはより高いレベルの概念です。
デザインパターンは、従来のプログラミング言語のアルゴリズムと同様の役割を果たします。デザインパターンは、オブジェクトを作成して組み合わせて、いくつかの便利なタスクを実行する方法を示します。最高のアルゴリズムと同様に、最高のデザインパターンは、さまざまな一般的な問題に適用できるほど一般的です。
オブジェクト指向コードと手続き型コードには、異なる拡張ポイントがあります。オブジェクト指向ソリューションでは、既存の関数を変更せずに新しいクラスを簡単に追加できます (Open-Closed Principle を参照)。手続き型コードでは、既存のデータ構造を変更せずに関数を追加できます。多くの場合、予想される変更の種類に応じて、システムのさまざまな部分でさまざまなアプローチが必要になります。
オブジェクト指向があまり良くない場所は、SQL のようにデータの「セット」を扱っている場所です。OO は、2 つのセットの交点または 2 つのセットのスーパーセットを最適に取得するように実際には設計されていないため、セット ベースの操作をより困難にする傾向があります。
また、 MSDNから取った次の例のように、機能的なアプローチがより理にかなっている場合もあります。
たとえば、XML ドキュメントを別の形式のデータに変換するプログラムを作成することを考えてみましょう。XML ドキュメントを解析し、さまざまな if ステートメントを適用してドキュメントのさまざまなポイントで実行するアクションを決定する C# プログラムを作成することは確かに可能ですが、間違いなく優れた方法は、変換を eXtensible Stylesheet として作成することです。言語変換 (XSLT) プログラム。驚くべきことではありませんが、XSLT の内部には機能主義の大きな流れがあります。
与えられた問題を「もの」の観点から考えると役立つことがわかりました。
問題が 1 つまたは複数の「もの」を持つと考えることができる場合、各「もの」には、その状態を参照する多数の属性または情報の断片と、それに対して実行できる多数の操作があります - OOPおそらく行く方法です!
OO を使用すると、オブジェクトに関連するロジックを 1 つの場所 (クラスまたはオブジェクト) 内に配置できるため、分離してデバッグと保守が容易になります。
私が観察したことは、すべてのアプリは OO と手続き型コードの組み合わせであり、手続き型コードはすべてのオブジェクト (少なくともメイン関数のコード) を結合する接着剤であるということです。手続き型コードを OO にできるほど、コードの保守が容易になります。
OOP がプログラミングに使用される理由:
- その柔軟性 - OOP は、実装の使用に関して非常に柔軟です。
- ソース コードを 99.9% 以上削減できます。誇張しすぎているように聞こえるかもしれませんが、本当です。
- セキュリティの実装ははるかに簡単です – Web 開発に関しては、セキュリティが重要な要件の 1 つであることは誰もが知っています。OOP を使用すると、Web プロジェクトでのセキュリティの実装が容易になります。
- コーディングがより整理されます – クリーンなプログラムがクリーンなコーディングであることは誰もが知っています。手続き型の代わりに OOP を使用すると、物事がより整理され、体系化されます (明らかに)。
- チームが互いに簡単に作業するのに役立ちます。チームプロジェクトを経験したことがある/経験したことがある人もいれば、同じ方法、実装、アルゴリズムなどを持つことが重要であることを知っている人もいます。
私の意見では、それはあなたの人としての質問です。関数の観点から考える人もいれば、クラスやオブジェクトを好む人もいます。OOP は、あなたの内部 (主観的) な世界のメンタル モデルと一致する場合により適していると言えます。
OOPは、物事があるときに役立ちます。ソケット、ボタン、ファイル。クラスをerで終了すると、ほとんどの場合、クラスのふりをしている関数になります。TestRunnerは、おそらくテストを実行する(そしておそらく実行テストという名前の)関数である必要があります。
問題によって異なります。OOPパラダイムは、ユーザーのアクション中に多数のエンティティが存在する分散システムまたはフレームワークを設計するのに役立ちます(例:Webアプリケーション)。
しかし、数学の問題がある場合は、関数型言語(LISP)を好むでしょう。パフォーマンスが重要なシステムの場合は、ADAやCなどを使用します。
言語OOPは、プログラムの実行時にガベージコレクター(メモリの自動使用)を使用する可能性があるため便利です。Cでプログラムを行う場合、メモリの問題を手動でデバッグして修正する必要があります。
個人的には、大規模なアプリケーションには OOP が実質的に必要だと思います。OOP を使用せずに 10 万行を超えるコードを持つプログラムを作成することは想像できません。メンテナンスと設計の悪夢になるでしょう。
OOPが悪いときは教えてください。
アーキテクトが非常に複雑で文書化されていない OOP コードを作成する場合。プロジェクトの途中で去ります。また、彼がさまざまなプロジェクトで使用した共通コードの多くには、コードが欠落しています。.NET Reflector に感謝します。
また、組織は Visual Source Safe または Subversion を実行していませんでした。
そしてごめんなさい。ログインするための 2 ページのコードは、かわいらしく OOP されていても、かなりばかげています....