OOPについての考え

「C ++でのプログラミングの基本」に関する別の記事では、多くのプログラマーがオブジェクト指向プログラミング(OOP)の本質を理解していないと考えるようになりました。







特に、この記事では

"++ , ++ . "







かなり前のフォーラムの1つで、「ユニバーサル」オブジェクト用にストレージシステムをプログラミングしたい別のプログラマーの推論に出会い、椅子がオブジェクトかどうかについて話しました。



これらの人々は両方とも何らかの形でOOPについて間違っています。



通常、OOPのオブジェクトは、実世界のオブジェクトとは関係ありません。 さらに、1つの場所(レコード内)に何らかの特性のセットを収集したとしても、OOPの理解の対象にはなりません。



「オブジェクト」という使い古された言葉のせいで、しばしば混乱が生じます。 さらに、「クラス」と「オブジェクト」の概念はしばしば混同されます。



したがって、OOPがどこにあり、どこにないのかを簡単に理解できるようにする単純なルール。



ヘッドライトとベルト



行動と条件



より広範囲では、オブジェクトのクラス(OOPの理解で)は次の場合に使用されます。



...一部のエンティティには、そのエンティティの内部状態に依存する動作があります。



「エンティティには状態があります」とは何ですか? それを理解しましょう。



エンティティインスタンスには独自のデータセットがあります-これは明らかです。 通常のレコード(構造)との違いは何ですか?



まず第一に、状態は、データの一部が本質的に「自分自身のために」使用されて、自分の行動を実装することを意味します。 エンティティに「隠すものがない」場合、通常のデータレコードに縮退します。 さらに、「状態」の概念は、「追加のデータセット」よりも厳密です。 これには、これらの内部データの一貫性、相互依存性が含まれます。 状態は正しい場合と正しくない場合があります。 そして、誰がこれを理解できますか? 外部オブザーバー? いいえ、本質だけです。 したがって、状態は理由で隠され、エンティティの無能なユーザーによる損傷から保護されます。



現在、エンティティの「動作」が何であるかが明らかになってきています。 これは、状態の正確性を維持しながら、エンティティが何らかの機能を実装する場合です。



簡単な例を見てみましょう。 製品があります:名前、単価、在庫残高。 これはOOPオブジェクトですか?



さらに読む前に考えてください。



その特性に制限を課さない場合-いいえ。 状態は発生しません。

任意の値を入力できます。 隠すものは何もありません。



制限を導入しましょう-残高を負にすることはできず、価格は正でなければなりません。



そして今?



外部ユーザーが製品のデータを任意に変更できるようになりましたか? 明らかにそうではありません。 私たちの製品には振る舞いがあります-残高の減少は「商品を一定の金額で受け取る」ことを意味し、残高を超える金額を受け取ることはできません。



何が起こったのか気づきましたか? 制限を導入しました。つまり、エッセンスの特性の性質に何らかの意味がありました。 そしてすぐに意味のある行動が現れました-「商品を持ち込む」、「商品を拾う」。



別の例。 プログラムがモジュールの動的な読み込みを必要とすると仮定します。 条件があります-既にロードされたモジュールのセット。 動作は簡単に確認できます-「モジュールをロード」、「モジュールをアンロード」。 なぜこの例ですか? さらに、現実世界のオブジェクトとの関係については言及されていません。



PLOのクラスの性質を現実世界のオブジェクトの性質と結びつけることは、かなりばかげて無意味な仕事です。 エッセンスの性質は、実世界ではなくシステムによって決定され、エッセンスの環境、その使用、コンポーネントの相互接続に依存します。



以上です。 カプセル化と呼ぶことができます。 そして、あなたは電話することはできません。 継承について長い間話すことができます。 または、「継承」がオブジェクトの動作を拡張する方法であることを簡単に理解できます。



主なことは、プログラマーが開発の複雑さを制御するためにOOPを必要とすることを理解することです。 そして、「現実世界のオブジェクトを反映する」ためではありません。



UPD



さて、スマートな言葉を投げ続けましょう。



抽象化とポリモーフィズムは、OOPに直接関連していません。 奇妙なことに。



すべてのプロシージャまたは関数は抽象化です。 どれでも。 発表は次のとおりです。



void sort(int *配列、intサイズ);



この関数は抽象化です。 ソートを実装します。 抽象的に。 方法はわかりません。

ただし、出力はソートされた配列になります。 抽象化はありますが、OOPはどこにありますか? OOPはありません。 オブジェクトもクラスもありません。



ソートポインターを宣言しました。 そして、私は彼にこの機能を割り当てることができます:



void quick_sort(int *配列、intサイズ)



またはそのような:



void bubble_sort(int *配列、intサイズ)。



多型がありました。 関数ポインタは同じままです。 しかし、現在では、異なるアルゴリズムが同じ関数ポインターの背後にあります。



OOPはどこですか? OOPは存在しません。 C ++でもないため、Cです。クラスはありません。 そして、抽象化と多態性が達成されます。



え?



UPD2



: - ;)



C, , this , , , this. ?



python, , ( ) - ?









ここにある。 私はこれについて話している:-) C ++が必ずしもOOPであるという行を書いたことはありません。 そして、残りはおそらくそうではありません。



OOPは言語機能ではありません。 いや! これがアプリケーションのアーキテクチャであり、サブジェクト領域をモデル化する方法です。 エンティティへの分割は、記事で説明されている原則に従って使用されます。



この言語の機能は、OOPの原則の適用を促進する場合がありますが、干渉することはありませんが、これらの原則の適用を複雑にする場合があります。 しかし、原則はこれから変わりません。



C ++で「悪い」クラスを作成できます。 調整された状態変化の原則に違反します。



そして、CまたはPythonで「正しい」OOPを実装できます。 または、アセンブラーでも。 エンティティを強調し、外部から状態を変更することを許可しません。



私の記事の主なアイデアは、コンパイラー機能に関するものではありません。



そして、OOPを使用しているプログラマーが考えるのは、「ここに(オブジェクトの)クラスが必要かどうか」です。



振る舞いがある状態がある場合、それは必要です;そうでなければ、それは必要ありません。



彼がプログラミングツールにこれを実装する方法は、私にとって重要ではありません。






All Articles