「OOPは状態を隠す」とはどういう意味ですか?[閉まっている]


11

cat-v.org上の多くの抗OOPの暴言の一つ、私は以下の通りであったそのうちの一つOOPモデルに対して複数の異議を上げるジョー・アームストロングの通路を見つけました:

異論4 –オブジェクトにはプライベート状態があります

国家はすべての悪の根源です。特に、副作用のある機能は避けてください。

プログラミング言語の状態は望ましくありませんが、現実の世界では状態が豊富です。私は銀行口座の状態に非常に興味があり、銀行に入金または引き出しを行うと、銀行口座の状態が正しく更新されることを期待しています。

状態が現実の世界に存在する場合、プログラミング言語は状態を処理するためにどの機能を提供する必要がありますか?

OOPLは「プログラマーから状態を隠す」と言います。状態は非表示であり、アクセス関数を介してのみ表示されます。従来のプログラミング言語(C、Pascal)は、状態変数の可視性は言語のスコープルールによって制御されると言います。純粋な宣言型言語は、状態がないと言います。システムのグローバルな状態はすべての機能に持ち込まれ、すべての機能から出てきます。モナド(FPL用)やDCG(ロジック言語)などのメカニズムは、プログラマーから状態を隠すために使用され、「状態は重要ではないかのように」プログラムできますが、必要に応じてシステムの状態に完全にアクセスできます。

OOPLによって選択された「プログラマーから状態を隠す」オプションは、最も悪い選択です。国家を明らかにし、国家の迷惑を最小限に抑える方法を見つけようとする代わりに、彼らはそれを隠します。

これはどういう意味ですか?私は、ほとんどの場合OOPの低レベルまたは手順の経験がほとんどないため、これがおそらく私がこれに慣れていないことを説明しています。そして、より現代的な観点から、オブジェクト指向のヒステリーのほとんどが渡されたので(少なくとも私が知る限り)、あなたはあなたはその通過がどれほど正確/関連していると思いますか?

ご協力いただきありがとうございます。



1
あなたが私に尋ねると、あなたがリンクした記事はいくつかの非常に貧弱な議論をします(文章の質は言うまでもありません)。私はそれが言っていることであまり多くの在庫を入れません。
ベンジャミンホジソン14

1
ああ。ますます私はこの「不変」なもの全体が宗教の悪臭を放ち始めている良い考えだと思っています。
ロブ14

3
Joe Armstrongは、OOに対する彼の異議は、OOが何であるかについての深刻な誤解に基づいていることを公に認めています。彼は、Erlangが実際にはオブジェクト指向の深い言語であることに気付きました(実際、主流で使用されている最もオブジェクト指向の言語かもしれません)。
ヨルグWミットタグ14

9
ジョー・アームストロングの暴言のarchive.orgの最初の捕獲は2001年4月からです。ジョーは2003年に論文を書きました。論文を書いている間、彼はオブジェクト指向について多くを学び、 OOは何らかの形で可変状態に関連しているという一般的な誤解(そうではなく、可変状態は完全に直交しています)。それ以来、彼はオブジェクト指向に対する批判が間違っていたこと、そして皮肉なことにErlangは実際にはオブジェクト指向言語である(メッセージがあり、プロセスと呼ばれるオブジェクトがあり、カプセル化されている)ことを認めました。
ヨルグWミットタグ14

回答:


32

これはどういう意味ですか?

このコンテキストでは、OOPはプログラマーからプログラムを隠しますが、(漏れやすい)アクセサーメソッドを介して表示できるようにすることで、プログラムの状態を隠します。論拠は、状態を不明瞭にすることで、作業が難しくなり、拡張により多くのバグが発生することです。

パッセージはどの程度正確/関連性があると思いますか?

私はそれが関連していると思うが、誤った方向を向いている。クラスがその状態の概念を外部に漏らしている場合、絶対に問題があります。クラスが外部の世界によって操作されるべき状態を隠そうとする場合、絶対に問題があります。ただし、それはOOP全体の失敗ではなく、クラスの個々の設計によるものです。状態自体を隠すことが問題だとは言いません-モナドは関数型プログラミングでこれを常に行います。

最良の場合、OOPは関数型プログラミングと手続きの最適な組み合わせのように機能します。クラスの不変式を保護するために使用されるプライベートステートは隠されているが、自由があるため、人々は「ステートが重要ではないかのように」クラスを使用できますクラスの明確に定義されたパブリック状態を使用して、詳細を抽象化します。

OOPは、人々がこのベストオブケースを達成することを難しくしていますか?おそらく。「Javaスクール」とShape / Circle / RectangleまたはCar全体がWheelsを教えるOOのスクールは、おそらくアプローチ自体よりも多くの責任があります。現代のOOPは関数型プログラミングからかなりの部分を取り、不変のオブジェクトと純粋な関数を奨励し、継承を阻止して適切に機能するクラスの設計を容易にします。


3
「Javaスクール」全体について心から同意しますが、それはまったく好きではありません。どうもありがとうございました。できれば投票します。
ジェイク14

2
正確に言うと、一般にモナドは状態を隠しませんが、一部のモナドは隠します(IOなど)。とりわけstackoverflow.com/questions/2488646/…を
thSoft 14

2
+1。これはquestioneerは、リンク先の記事よりもはるかにバランスのとれた微妙な分析である
ベンジャミン・ホジソン

2
Joe Armstrongは、OOに対する彼の異議は、OOが何であるかについての深刻な誤解に基づいていることを公に認めています。彼は、Erlangが実際にはオブジェクト指向の深い言語であることに気付きました(実際、主流で使用されている最もオブジェクト指向の言語かもしれません)。
ヨルグWミットタグ14

2
Jorg-Joeのフォローアップへのリンクを投稿できますか?私はそれを読むことに本当に興味があります。そして、@ radarbob、すぐに!
user949300 14

2

単一の明確な「所有者」を持たない可変状態の断片がある場合、システムについての推論は困難になります。つまり、オブジェクトが変更可能な状態になることは決してありませんが、変更可能な状態を持つオブジェクトは、所有権が不明な場合には使用しないでください。逆に、所有権を追跡せずに自由に渡す必要があるオブジェクトは、不変であること。

実際には、効率的なプログラミングでは、一部のオブジェクトが可変状態であることが頻繁に必要になります。ただし、そのような状態は非共有ワーカーオブジェクトに限定する必要があります。.NET のIEnumerable/ IEnumeratorインターフェイスを考慮してください。コレクションが実装する場合IEnumerable、アイテムを1つずつ読み取ることができます。コレクションを読み取る実際のプロセスでは、多くの場合、どの項目が読み取られたかを追跡する必要があります(可変状態の一部)が、そのような状態はの実装に含まれていませんIEnumerable。代わりに、コレクションからアイテムを読み取ることができる十分な状態を実装して含むオブジェクトを返すIEnumerableというメソッドを提供します。オブジェクトにそのような状態が含まれているという事実は問題になりませんが、GetEnumeratorIEnumeratorオブジェクトの実装IEnumeratorが共有されていない場合

ほとんどの場合の最良のパターンは、自由に共有されているが変更されない(少なくとも共有された後は)オブジェクトと、明確な所有者がいて、その所有者が自由に変更できるオブジェクトの混合物を使用することです、しかし誰とも共有されることはありません。


不変であるべきものと可変状態にできるものとの間の優れた区別。これを読んで、最近のオブジェクトグラフ(以前より不変)が基本的にこのガイドラインに従っていることに気付きました。これは、よく耳にする「変な状態は常に悪」であるホグウォッシュに対する良い中程度の解毒剤です。
マイクはモニカをサポートします14

@マイク:本当の問題は、Javaと.NETのすべてのオブジェクト参照が完全に無差別であることだと思います。オブジェクトへの参照を取得または受信するコードは、制限なく他のコードと共有できます。どちらのフレームワークにも共有不可能な参照フィールドの概念はありません。.NETの構造体とbyrefは近づきますが、実行できることや外部コードが実行できないようにすることに関しては、かなり制限されています。いずれにせよ、私は可変状態に関して基本的なことわざを提供します:12:57 amに、オブジェクトが同時に表すことができる...
supercat

...実世界のオブジェクトの現在の状態、およびオブジェクトが12:57 amに持っていた状態。オブジェクトの実世界の状態が変化すると、オブジェクトが両方を表すことはできなくなります。オブジェクトが12:57 amの状態を表すようにする必要がある場合と、現在の状態を表す場合があります。ただし、現在の状態が変化した場合、12:57am状態と現在の状態との関係は維持できません。
supercat 14

0

質問に答える以上の危険を冒すと、OOPのアイデアに欠陥が見られやすくなりますが、アイデアの力は悪用される能力に反映されると思います。

結局のところ、誰もが自分の好きな言語を持っているので、「非常に強力」という言葉で説明し、本当に好きだということです。しかし、計算の普遍性の不思議は、言語がどれほどすばらしいものであっても、それが本当に強力であれば、アセンブリ言語をシミュレートできることです。そして、できれば、誰かがそれを確認します。(アセンブリ言語に問題があるわけではありません。)

OOPの時流についての私の個人的な感覚は、それがソフトウェアエンジニアリング/コンピューターサイエンスにおける人々の教育の阻害を表しているということです。彼らは、それがすべてデータ構造に関するものだと考えるレベルで発育不良です。クラス、継承、コンテナ、イテレータ、ハッシュマップ、プロパティ、状態の非表示など-データ構造に関するすべて-より楽しい。

私は個人的に、人々が問題を言語的に見て解決することを学ぶ次のレベルを見たいと思っています。ドメイン固有言語の概念を理解する場合、それらを簡単に作成し、作成を問題解決の不可欠な部分にする方法。データ構造言語であると言っても間違いではありません。人々は言語設計のスキルを持っている必要がありますので、彼らはそれをただぶらぶらしているだけではありません。

それから次のレベルとして、人工知能が再び活性化するのを見たいです。プログラマがバイトやスレッド、仮想関数テーブル、CUDAを超えて、マシンを推論、学習、作成する方法に移行することを望んでいます。私はこれがフィールドの小さなコーナーで非常に遠くまで進んだことを知っていますが、十分に近い場所ではありません。


1
「本当に強力な場合は、アセンブリ言語をシミュレートできます」- powerfulすぐに定義を入れ替えます。他の人が言うときpowerful、彼らはそれがどれくらいうまくプログラマーを抽象化することができるかについて話します。これは計算力とは異なる話です。
フィル14

@Phil:アブストラクトはそれらの言葉の別の1つです:)
マイクダンラベイ

いや あなたは言葉について話していました。私はアイデアについて話していました。2番目と3番目の単語の使用はpower異なることを意味します。誤解しないでください。
フィル14

ところで、興味がある場合は、4番目の段落で言っているアプローチにいくらか近いRacketをチェックしてください(プログラマーが問題を解決するのではなく、言語を問題のレベルにすることができます)言語の固定された構成体のセット)。誰もが最初にそれを見たときにその印象を持っている場合に備えて、古典的なLisp / Schemeをはるかに超えています。
フィル14

0

アクセシビリティはOOPの機能ではなく、JavaやMicrosoft dotNETなどの実装に固有のものです。OOPを定義する主な機能は多態性です。

とにかく、オブジェクトの状態を隠すことで、意味のあるAPIを作成する方法はありません。プレゼンテーションは、実際のOOPの重要なコンポーネントです。同意しない人は、ソフトウェア業界に対して不合理な敵意を持っている可能性が高いため、私の意見からは自分の意見は無関係です。

あなたがリンクしたようなウェブサイトは、新技術に対する非常に厳格な考えと批判で有名です。一部の人々はそれを取得しません。


オブジェクトは、モデル化する概念の不変式を保護するために存在する必要があります。オブジェクトは時間と空間にわたって提示されるさまざまな方法をすべて理解できないため、プレゼンテーションはまったく別の関心事であり、同じオブジェクトで効率的かつ保守的に処理することはできません。目的が多目的で保守可能なオブジェクトである場合、プレゼンテーションはイベントストリーミングやマテリアライズドビューなどの他のメカニズムを通じて処理する必要があります。オブジェクトを変更する必要があるのは、その概念が修正されるか、不変式が変更される場合のみです。
アンドリューラーソン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.