非OOPパラダイムは、カプセル化などの概念をサポートしていますか?


12

オブジェクト指向プログラミングの重要な概念の1つはカプセル化です。ただし、最近のソフトウェアの世界は、関数型プログラミングなどの他のパラダイムに傾倒しているようです。

それは私に、カプセル化と他のOOP原則についてはどう思いますか?彼らは間違っていますか?

OOPが間違って適用されているのですか?たとえば、アランケイはOOPSLA'97基調講演で言ったことで注目されています。

Joe Armstrong-「オブジェクトは関数とデータ構造を分割できない単位でバインドします。関数とデータ構造はまったく異なる世界に属しているため、これは根本的なエラーだと思います。」




2
まず、カプセル化の意味とそれをサポートする言語にとっての意味を明確にする必要があります。
陶酔

14
この質問が何を求めているのか理解できません。カプセル化がOO(件名行)の外に存在できるかどうかを尋ねていますか?カプセル化が間違っているかどうか尋ねていますか(2番目の段落)?OOが間違って適用されているかどうかを尋ねていますか(3番目の段落)?そして、OPはジョーアームストロングの引用で何を言いたいのでしょうか。OPは「カプセル化」をどのように定義しますか?OPは「OO」をどのように定義しますか?それらの「他の教義」とは何ですか?
イェルクWミッターク

1
Robert Martinはかつて、OOPはカプセル化を取り除き、恐ろしいハックでパッチを元に戻したと述べました。「ooの前は完全にカプセル化されていました」。もちろん彼は双曲的でしたが、今では誰かがOOはカプセル化についてだと言うのを見るたびに、ボブおじさんを覚えています。
GnP

回答:


15

ここに陥った罠は、プログラミングパラダイム(構造化、オブジェクト指向、関数型など)の厳密な定義があると考えていることだと思います。

2人の異なる開発者にOOPの意味を尋ねると、2つの異なる答えが得られます。はい、専門職として、カレッジのOOPソフトウェアエンジニアリングクラスでカバーされるカプセル化、データ非表示などのいくつかの一般的なテーマがあることに同意します。

しかし、現実の世界では、物事はそれほど完全に乾燥しているわけではないため、2人の開発者が2つの異なる答えを出すのはこのためです。おそらく、彼らはOOPの概念を異なる方法で表現するさまざまな言語の専門家です。言語パラダイムは重複する傾向があります。2013年前後の最新の流行は、クロージャーまたはラムダを介してオブジェクト指向言語に関数型プログラミングを組み込むことです。Java 8はオブジェクト指向ですか、それとも機能的ですか?私はそれを少し機能的なオブジェクト指向と呼びます。他の誰かがそれを異なって説明するかもしれません。

OOPが間違って適用されているのですか?

いいえ、問題は、さまざまな言語がプログラミングの概念を異なる方法で表現していることです。おそらく、1つの言語でOOPの概念が省略されており、別の言語ではそれが含まれていますが、別のOOPの概念が省略されています。言語は通常、特定のタイプのタスクを簡単にするために設計されていますが、他のタスクをより困難にすることを犠牲にしています。それは正しいことでも間違っていることでもありません。それは回避することが不可能である実際のトレードオフにすぎません。

現実の世界は教室ではありません。抽象レベルで概念的なプログラミングパラダイムについて議論する必要があるか、または有用であるためにトレードオフを余儀なくされる実際のプログラミング言語について議論する必要があります。プログラミング言語がOOPの抽象的な定義によって主に定義されている限り、そのバケットにそれを含めることができます。


10

ただし、最近のソフトウェアの世界は、関数型プログラミングなどの他のパラダイムに傾倒しているようです。

それは議論の余地があります。まず、OOPと関数型プログラミング以外に広く議論されているパラダイムは見当たらないので、「他のパラダイムのような」というフレーズは忘れてしまいます。FPについてお話ししましょう。

関数型プログラミングがここ数年で非常に人気になった理由は、ここの他の質問で詳しく説明されています。これを繰り返すつもりはありません(たとえば、ここまたはここを参照してください)。しかし、私の意見では、これは「OOPは大きな間違いだった」、または「機能とOOPは相互に排他的である」という理由ではなく、ツールボックスを拡張して両方の世界のベストを獲得しようとする人々のようなものです。確かに、どちらか一方を好む強硬派である専門家は確かにいますが、両側にそれらの人がいます。

それは私に、カプセル化と他のOOP原則についてはどう思いますか?彼らは間違っていますか?

カプセル化には多くの異なるフレーバーがあります。関数型プログラミング言語と言語構造は、特定の形式のカプセル化、オブジェクト指向のその他のものを提供します。機能的手段によるカプセル化の例を探している場合は、クロージャーから始めます。

「他の教義」に関して:いいえ、それらは間違っていませんが、大規模な並列化のような特定のシナリオでは、機能的アプローチはおそらくより適切にスケーリングします。適切に設計されたUIフレームワークの作成などの他のシナリオでは、OOPアプローチはおそらくより適切にスケーリングします(YMMV、私は手元に優れた例しかないだけです)。さらに、ほとんどの現実世界のシナリオでは、特定のシステムがどれほど適切にスケーリングするかというお気に入りのプログラミングパラダイムを持つチームの知識と経験に依存することは間違いありません。

OOPが間違って適用されているのですか?たとえば、アランケイはOOPSLA'97基調講演で言ったことで注目されています。

確かにOOPは多くの人によって間違って適用されることが多いですが、FPについても同じことが言えると思います。そして、ジョンマクカーシー(Lispの設計者)が関数型プログラミングについて考えているときにJavascriptのようなことを念頭に置いていたら、私は驚かされます(私を憐れんでください、その比較のためにあまり私を怒らせないでください;-)

Joe Armstrong-「オブジェクトは関数とデータ構造を分割できない単位でバインドします。関数とデータ構造はまったく異なる世界に属しているため、これは根本的なエラーだと思います。」

アーランの発明者はいくつかの良い議論を持っていると思いますが、彼は彼自身の視点も持っているので、彼に彼の意見を聞かせてあなた自身の意見を構築してください。これについて異なる考えを持つ他の専門家はたくさんいます。


1
OOがGUIにとって特に優れているとは思えませんが、OOとGUIがほぼ同時に登場したということです。McCarthy / javascriptの場合は+1);)
jk。

1
公平を期すために、一部の人々は、既存のアプローチに欠陥があり、別のものに置き換えることができると提案しています。ツールボックスを「拡張する」と呼ぶか、それとも「改善する」と呼ぶかはわかりません

1
@AndresF。それは素晴らしい読み物です。時間があれば、その論文を詳しく検討するつもりです。
ロバートハーベイ

4

もちろん:

struct Foo
{
    string bar;
    int bux;
}

私はあなたが何を言おうとしているのか知っています。ええと、これについてはジョーアームストロングと一緒です。ファーストクラスのオブジェクトを必要とせずに、プログラム全体またはオペレーティングシステム全体を記述できます。Linuxはそれを証明しています。

Javascriptプログラマーはクラスとではなく、関数とクロージャーに定期的に状態と動作をカプセル化します。


3
小さじ1杯で土の丘をシャベルで掘ることもできます。しかし、それを行うのに最適な方法であると主張する人は誰でも疑いを持って見られるべきです。
陶酔

6
私はそれが最適だと言ったことは一度もありません、それはOPがとにかく求めていることではありません。他のニュースで、私はLinuxが小さじ1杯で土をかき混ぜるのに適しているのを面白いと思います。
ロバートハーベイ

2
@jk。もちろん。Cもそうです。
ロバートハーヴェイ

1
確かにそれは一種のない
JK。

4
Cの構造を「カプセル化」とは呼びません。データを保護することも、データにアクセスするための標準化された方法を必ずしも提供することもありません。手動のポインタ演算を行う必要がありません。たとえば、シリアル化されたパケットを構造体に、またはその逆にキャストするネットワークコードを見つけることはよくあることです。ネットワークのバイトオーダーが間違っていて、楽しい結果が得られます。
david25272

2

ここでの主な問題は、カプセル化が厳密に定義された概念ではなく、なぜそれが有用なのかということです。いくつかの調査を行うと、カプセル化を人々がどのように見るかは非常に意見が分かれており、多くの人々はそれを抽象化と混同していることを示しています。

最初に見つける定義は

カプセル化は、データとデータを操作する関数を結合する概念です...

これがあなたの定義である場合、ほとんどの言語は、データとそのデータで動作する関数をクラス、モジュール、ライブラリ、名前空間などにグループ化する方法を持っています。

しかし、その定義が続くので、それはカプセル化の主な目的ではないと主張します。

...そして、それは外部の干渉と誤用の両方から安全を保ちます。

ウィキペディアもそれに同意します:

オブジェクトのコンポーネントの一部への直接アクセスを制限するための言語メカニズム。

しかし今、私たちは「干渉と誤用」が何を意味するのか、そしてなぜデータへの直接アクセスが制限されるべきなのかを尋ねる必要があります。理由は2つあると思います。

1つ目は、データを変更できる範囲を制限することは、開発者の最大の利益になるということです。あまりにも多くの場合、値が設定される前/後にロジックを持つ必要があります。そして、値を設定できる場所の数が限られていることは非常に貴重です。OOP言語では、これはクラスを使用して行うことができます。「可変」関数型言語では、クロージャは同じ目的を果たします。そして、私たちはclasses = Closuresを知っているので、変更可能な関数型言語はOOPとは「パラダイム」が異なるため、議論の余地があります。

しかし、不変言語についてはどうでしょうか?変数を変更する問題はありません。ここで2番目の問題が発生します。関数とデータをバインドすると、そのデータを有効な状態に保つことができます。の不変の構造を想像してくださいEmail。この構造には単一のstringフィールドがあります。タイプの値がある場合Email、そのフィールドには有効な住所が含まれている必要があります。OOPのカプセル化ではprivate、そのフィールドを宣言し、Getメソッドのみを提供し、constructor method文字列で渡されたものが有効なアドレスである場合にのみ成功します。クロージャーについても同様です。さて、不変言語の場合、構造は特定の関数を介してのみ初期化でき、そのような関数は失敗する可能性があると言う方法が必要になります。そして、私はその基準に合う言語を知りません(たぶんコメントの誰かが私を啓発するかもしれません)。

最後の問題は、カプセル化を「サポートする」言語が意味するものです。一方には、カプセル化の強制を許可する言語があるため、カプセル化が壊れている場合、コードはコンパイルされません。反対に、言語はカプセル化を行う方法を提供するかもしれませんが、それはそれを強制しません、開発者がそれを自分で強制することを残します。2番目のケースでは、構造と関数を持つ任意の言語が機能します。動的言語とHaskellが思い浮かびます。そして、私はスペクトルの反対側に該当する言語は多くはないと思います。オブジェクトのカプセル化を強制するのに非常に優れているC#でも、リフレクションを使用してバイパスできます。しかし、C#で見た場合、大量のコードのにおいであると見なされ、健全なC#開発者が喜んでそうすることはありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.