抽象化とは何ですか?[閉まっている]


38

プログラマーが使用するような、プログラミングの抽象化とは何かについて一般的に合意された定義はありますか?[注意、プログラミングの抽象化は、「抽象化」という単語の辞書定義と混同しないでください。]明確な、または数学的な定義さえありますか?抽象化の明確な例は何ですか?


..これを投稿するときにロボットではないことを証明することを余儀なくされることは、本当にあまりにも多くを求めていることを示唆しています:)
mlvljr

8
「数学的に」とはどういう意味ですか?私は抽象化を数学的な概念とは本当に考えません。
フィッシュトースター

2
@mlvljr:申し訳ありませんが、私はまだ従うかどうかわかりません。抽象化とは、何かをより簡単に処理する方法を提供することです。フォーマルなツール/メソッドがどのように関係しているのかわかりません。
フィッシュトースター

1
@mlvljr、数学の例、またはすべてのプログラミング抽出をカバーする数学が必要ですか?私は後者が存在するとは思わない。
C.ロス

8
Perhpas cstheory.stackexchange.comは、この質問のための右の場所である
コンラッドFrix

回答:


46

「プログラミングの抽象化が何であるかを数学的に定義できますか?」に対する答え。「いいえ」です 抽象化は数学的概念ではありません。レモンの色を数学的に説明するように誰かに頼むようなものです。

適切な定義が必要な場合:抽象化は、特定のアイデアからより一般的なアイデアに移行するプロセスです。たとえば、マウスを見てください。ワイヤレスですか?どんなセンサーがありますか?ボタンはいくつありますか?人間工学的ですか?それはどれくらい大きいですか?これらのすべての質問に対する答えは、マウスを正確に説明することができますが、答えが何であるかに関係なく、ボタンを備えたポインティングデバイスであるため、マウスのままです。マウスになるのに必要なのはそれだけです。「Silver Logitech MX518」は具体的で具体的なアイテムであり、「マウス」はその抽象化です。考えるべき重要なことは、「マウス」のような具体的なオブジェクトはないということです。それは単なるアイデアです。あなたの机の上のマウスは常にもっと具体的なものです-それは

抽象化は階層化することができ、好きなだけ細かくまたは粗くすることができます(MX518はポインティングオブジェクトであるマウス、コンピューター周辺機器であり、電気で動くオブジェクトです)、あなたが望む限り行くことができます、ほぼすべての方向(マウスにはワイヤがあります。つまり、ワイヤでオブジェクトとして分類できます。また、底面が平らなので、回転しないオブジェクトの種類として分類できます。傾斜面に直立して配置されます)。

オブジェクト指向プログラミングは、抽象化とそのファミリまたはグループの概念に基づいて構築されています。優れたOOPとは、プログラムのドメインで意味を持ち、「漏れない」適切な詳細レベルで優れた抽象化を選択することです。前者は、マウスを傾斜面で回転しないオブジェクトとして分類することは、コンピューター機器のインベントリを作成するアプリケーションには意味がありませんが、物理シミュレーターには意味があることを意味します。後者は、ある種のオブジェクトにとって意味をなさない階層への「ボックス化」を避けることを試みるべきであることを意味します。たとえば、上記の私の階層では、すべてがコンピュータ周辺機器は電気で駆動されていますか?スタイラスはどうですか?スタイラスを「周辺」カテゴリにグループ化する場合、電気を使用しないため問題が発生します。また、コンピューター周辺機器を電気を使用するオブジェクトとして定義します。円楕円の問題は、この難問の最もよく知られた例です。


2
見えると思う。具体的には、メソッドまたは関数を抽象的な方法で、つまり実装ではなくそのコントラクトで参照することについて話しています。あなたの声明は正しいです、そして、これは用語の完全に有効な使用です。メソッド呼び出しは、ある種の具体的な動作の抽象化です。
-nlawalker

4
@nlawalker:抽象化と一般化を混ぜています。それらは同じものではありません。あなたが説明しているのは後者です(「特定のアイデアからより一般的なアイデアへの移行」)。抽象化は、具体的なものから抽象的なものへと移ります。たとえば、7個の青いビー玉と7個の赤いビー玉を持ち、「同じ数の同じ数のビー玉を2セット持っています」と言います。 (クラスと同等のセット)。ところで、自然数nは、カーディナリティnのすべての同等なセットのクラスであり、それらのセット間の1対1マッピングによって定義される非円形です。
pillmuncher

33
数学的には、レモンの色は約570 nmの波長の光です。
エリック

1
@Erikそれを書くつもりだった。ああ!
ゲイリーロウ

1
@Erikそれは数学ではなく物理学です:)数学は「光」などの概念について何も知りません。光は経験的です。数学はそうではありません。
アンドレスF.

25

私はほとんどの答えに断固として同意しません。

これは私の答えです:

GとHの2つのセットが与えられた場合、ガロア接続(アルファ、ベータ)をそれらの間で定義でき、一方は他方の具体化であると言えます。接続を逆にすると、一方は他方の抽象化になります。これらの関数は、具体化関数と抽象化関数です。

これは、コンピュータープログラムの抽象解釈の理論に基づいています。これは通常、これまでの静的分析アプローチです。


8
わかり

@マイク:イェーイ?:-)
ポールネイサン

ああ、例はありますか?
mlvljr

2
@mlvljr:di.ens.fr/~cousot/AI astree.ens.frはデータのスケッチを提供します。
ポールネイサン

1
アミール:静的解析の世界からの抽象化の技術的な定義です。
ポールネイサン

13

抽象化は、より重視されWhat、あまり重視されませんHow。または、必要なことだけを知って、他のすべてのサービスについてプロバイダーを信頼するだけです。サービスプロバイダーの身元を隠すことさえあります。

たとえば、このサイトは、質問をして回答するためのシステムを提供します。ここのほとんどの人は、このサイトの質問、回答、投票などの手順を知っています。しかし、基礎となるテクノロジーが何かを知っている人はほとんどいません。サイトがASP.net mvcまたはPythonで開発されたかどうか、これがWindowsまたはLinuxサーバーなどで実行されているかどうかなど。そのため、このサイトは、サービスを提供する私たちにその基礎となるメカニズムの上に抽象化レイヤーを保持しています。

他の例:

  • 車はすべてのメカニズムを隠しますが、車を運転し、燃料を補給し、所有者に維持する方法を提供します。

  • APIは、他のプログラマにサービスを提供する実装の詳細をすべて隠します。

  • OOPのクラスは、プライベートメンバーと、パブリックメンバーを呼び出すサービスを提供するパブリックメンバーの実装を隠します。

  • 型のオブジェクト使用している間Interfaceabstract classJavaやC ++での、実際の実装が隠されています。また、隠されているだけでなく、で宣言されてInterfaceいるメソッドの実装も、さまざまな実装/継承クラスで異なる可能性があります。ただし、同じサービスを取得しているので、Howそれが実装されており、正確にWho/ Whatサービスを提供していることを気にしないでください。

  • アイデンティティの隠蔽:「サムはコンピュータープログラムを作成できることを知っている」という文章の場合。「サムはプログラマーです。プログラマーはコンピュータープログラムの書き方を知っています。」2番目のステートメントでは、人は重要ではありません。しかし、彼のプログラミング能力は重要です。


それで、なぜそれを単に「何の正確な仕様」と呼ぶのですか?
mlvljr

また、
サトリビットの

@mlvljr Howを理解するのに少し役立ちますWhat。したがって、抽象化と組み合わせることができます。
グルシャン

7

プログラミングの抽象化は、問題の単純化されたモデルです。

たとえば、TCP / IP接続はデータ送信の抽象化です。IPアドレスとポート番号を含めるだけで、APIに送信できます。ワイヤ、信号、メッセージ形式、および障害のすべての詳細に関心があるわけではありません。


あぁ!ここで簡略化されたモデルとは何ですか?ところで、漏れやすいパズルを覚えていますか?:)
mlvljr

7

抽象化は、定理のプログラミングバージョンにすぎません。

正式なシステムがあり、そのシステムについての考えを提案します。あなたはそれを証明し、うまくいけば定理があります。あなたの定理が成り立っていることを知ってから、システムについてのさらなる証明でそれを使うことができます。システムによって提供されるプリミティブ(if文やint値型など)は一般に公理と見なされますが、マシンコードで記述されたCPU命令ではないものは一種の抽象化であるため、厳密には真実ではありません。

関数型プログラミングでは、数学的ステートメントとしてのプログラムの概念は非常に強力であり、型システム(Has​​kell、F#、またはOCAMLなどの強力で静的に型付けされた言語)を使用して、証明を通じて定理をテストできます。

たとえば、プリミティブ演算として加算および等価チェックを、プリミティブデータ型として整数およびブール値を持っているとしましょう。これらは公理です。それ1 + 3 == 2 + 2が定理であると言えば、それから加算と整数と等式のルールを使用して、それが真のステートメントであるかどうかを確認できます。

ここで、乗算が必要であり、プリミティブを(簡潔にするために)ループ構造とシンボリック参照を割り当てる手段が含まれているとします。提案できる

ref x (*) y := loop y times {x +}) 0

私はそれを証明したふりをして、乗算が成り立つことを示します。これで、乗算を使用して、システム(プログラミング言語)でより多くのことができるようになりました。

型システムも確認できます。(*)タイプはint-> int-> intです。2つのintを取り、intを出力します。加算のタイプはint-> int-> intであるため、(rest)がintになる限り、0 +(rest)が保持されます。私のループはあらゆる種類のことを実行できますが、(x +(x +(x ... + 0)))が結果となるようなカリー化された関数のチェーンを出力すると言います。その追加チェーンの形式はちょうど(int->(int->(int ...-> int)))ですので、最終的な出力はintになります。したがって、私のタイプシステムは、他の証明の結果を保持しました。

この種のアイデアを長年にわたって、多くのプログラマー、そして多くのコード行にわたって組み合わせれば、最新のプログラミング言語、つまり「実証済みの」コード抽象化の心のこもったプリミティブのセットを手に入れることができます。


4

ウィキペディアの答えは十分でしょうか?http://en.wikipedia.org/wiki/Abstraction_%28programming%29

コンピュータサイエンスでは、抽象化のメカニズムと実践により詳細が削減され、一度にいくつかの概念に集中できるようになります。


そして、抽象化されたものの例は何でしょうか?
mlvljr

3
@mlvljr:ウィキペディアの記事を読むと、いくつか表示されます。
ジョンフィッシャー

悲しいことに、私はそれらがあまりにも抽象的すぎると確信しています。
mlvljr

4

数学的には、「整数」は抽象化です。そして、すべての整数に対してx + y = y + xのような形式的証明を行う場合、3や4などの特定の数値ではなく、抽象化「整数」を使用します。レジスタおよびメモリ位置より上のレベルのマシン。ほとんどの場合、より抽象的なレベルでより強力な思考を考えることができます。


使用しません。IInt add(IInt a, IInt b);あなたがプログラムにサブルーチン事前に知っていることabなり、言うInt128: IInt多かれ少なかれ良い例を?あなたのコードの部分を持っている--ieそれが行います(証明できるもの)を知ること、行うことになっている何をあなたが必要なものをあなたはそれを行うにすると同時に(他方では)物事を正確にあなたをそれなしでそれを知る必要はありません(他のコンテキストでもそのことを使用する能力を持つ)?
mlvljr

1
申し訳ありませんが、質問を理解できません。
ケイトグレゴリー

さて、2から3を追加する必要があるプログラムを書いているとします。これを行うには、add(int, int)サブルーチン/関数を呼び出します。return 2 + 3;この場合に持っていれば十分です。そして、なぜ「普遍的な」ルーチンを使用する必要がありますか(return a + b;つまり、提供された実際の パラメータabパラメータで動作するため、値から真に抽象化されます)-それは上記の私の(修辞的な)質問でした。それがもう少し明確になったことを願っています。
mlvljr

私の最初のコメントはかなり「自己難読化」されています、私は同意します:)
mlvljr

4

ここで良い答えを得ています。私はただ警告します-人々は抽象化は何らかの形で台座に置かれる必要があるこの素晴らしいものであり、あなたが十分に得ることができないと考えています。そうではない。それはただの常識です。物事間の類似性を認識するだけなので、問題の解決策をさまざまな問題に適用できます。

頑張って...

私の悩みのリストの上位にあるのは、人々が「抽象化の層」についてそれが良いことであるかのように話すときです。彼らは、気に入らないクラスやルーチンを「ラッパー」にして、「もっと抽象的」と呼びます。「プリンセスとエンドウ」のf話を覚えていますか?プリンセスはとても繊細だったので、マットレスの下にエンドウ豆があると眠れず、マットレスの層を追加しても助けにはなりませんでした。「抽象化」の層をさらに追加すると役立つという考えは、そのようなものです-通常はそうではありません。つまり、ベースエンティティへの変更は、コードの複数のレイヤーに波及させる必要があるということです。


抽象化を「はっきりと知覚するにはあまりにも美しい(または、さらにドライな(数学的な)用語で説明するには)美しすぎる」と考えることは、それが何であるかを(最初に、少なくとも)理解するのに役立ちません。アプリケーションと(ホラー!)評価[与えられたコードがどのように、どのように抽象的であるか]
mlvljr

3
1つの場所での変更により、他の場所で複数の変更を行う必要がある場合、抽象化は不適切です。本質的には、私や他の誰かが抽象化の面で間違いを犯したことはないとは言いませんが、その狂気には方法があります。優れた抽象化は、疎結合コードの基礎です。適切な抽象化を考えると、変更は途方もなく簡単になります。そのため、私は台座に抽象化を施し、適切なものを見つけるのに膨大な時間を費やしています。
ジェイソンベイカー

@Jason Baker私たちの抽象化手法を効果的に使用するのに十分具体的にしましょう
...-mlvljr

1
@Jason:「1つの場所での変更により、他の場所で複数の変更を行う必要がある場合、抽象化は不適切です。」私はあなたと一緒です。私は悪いものに囲まれているようです。
マイクダンラベイ

1
開発者が壮大なビジョンを持っていた場所で働いていたようで、チームを集中させる強力なボスがいなかったようです。そのような環境にいると、別の仕事を探し始めます(プロジェクトの予算は常に超過している、または十分に小さい会社=>破産)。最近ツイートを見ました。「スパゲッティコード」対「ラザニアコード」、後者はレイヤーが多すぎる場合です。
yzorg

4

漏れやすい抽象化に関する私のブログ投稿が役立つと思うかもしれません。関連する背景は次のとおりです。

抽象化は、関連するプログラムフラグメントのセットに共通するものを取得し、それらの違いを取り除き、プログラマがその抽象概念を表す構造を直接操作できるようにするメカニズムです。この新しいコンストラクトには、(実質的に)常にパラメーター化があります。これは、特定のニーズに合わせてコンストラクトの使用をカスタマイズする手段です。

たとえば、Listクラスはリンクリストの実装の詳細を抽象化できます。操作nextpreviousポインターの観点で考える代わりに、シーケンスに値を追加または削除するレベルで考えることができます。抽象化は、より原始的な概念の非常に小さなセットから、便利で豊富で、時には複雑な機能を作成するための不可欠なツールです。

抽象化はカプセル化とモジュール性に関連しており、これらの概念はしばしば誤解されます。

このList例では、カプセル化を使用して、リンクリストの実装の詳細を隠すことができます。たとえば、オブジェクト指向言語では、これらのフィールドへのアクセスが許可されているのはリスト実装のみであるプライベートnextおよびpreviousポインタを作成できます。

カプセル化は抽象化には十分ではありません。これは、必ずしも構造の新しい概念または異なる概念があることを意味するわけではないためです。すべてのListクラスが ' getNext' / ' setNext'スタイルのアクセサメソッドを提供する場合、実装の詳細からカプセル化されます(たとえば、フィールドに名前を付けたのは ' prev'または ' previous'?その静的型は何ですか?)抽象度が非常に低くなります。

モジュール化情報の隠蔽に関係します。安定したプロパティはインターフェイスで指定され、モジュールはそのインターフェイスを実装し、モジュール内のすべての実装の詳細を保持します。他のモジュールは安定したインターフェイスのみに依存しているため、モジュール性はプログラマが変更に対処するのに役立ちます。

情報の隠蔽はカプセル化によって支援されます(コードが不安定な実装の詳細に依存しないように)が、モジュール化のためにカプセル化は必要ありません。たとえば、あなたが実装することができますList「暴露する、Cにおける構造をnext」と「prev世界に」ポインタを、だけでなく、インターフェイスを提供し、含むinitList()addToList()と、removeFromList()関数。インターフェイスのルールに従っている場合、データ構造が常に有効な状態であることを保証するなど、特定のプロパティが常に保持されることを保証できます。[例えば、モジュール性に関するParnasの古典的な論文は、アセンブリの例を使って書かれました。インターフェイスは、契約に関するものであり、設計に関するコミュニケーションの形式であり、必ずしも機械的に確認する必要はありませんが、今日はそれを信頼しています。

抽象、モジュラー、カプセル化などの用語は、ポジティブなデザインの説明として使用されますが、これらの品質のいずれかが存在しても良いデザインが自動的に得られないことを認識することが重要です。

  • n ^ 3アルゴリズムが「適切にカプセル化」されている場合、改良されたn log nアルゴリズムよりもパフォーマンスが低下します。

  • インターフェイスが特定のオペレーティングシステムにコミットする場合、たとえば、ビデオゲームをWindowsからiPadに移植する必要がある場合、モジュラーデザインの利点は実現されません。

  • 作成された抽象化があまりにも多くの不必要な詳細を公開する場合、独自の操作で新しい構成を作成できません。それは単に同じものの別の名前になります。


まあ、それは私が実際に望んでいたことのようです(「モジュラー== abstract == good == you-can-never-estimate-it-just-struggle」ビューのいくつかの常識/例-証明された「暴言」) 、おかげで(まだ読んで)
-mlvljr

そして、ここに私の今後の回答(私の質問に対する)からの挑発的なモットーがあります。「心が弱くなるとアブストラクションが漏れる」;)
mlvljr

2

OK、私はあなたが何を求めているのかを理解したと思います:「「抽象化」の数学的に厳密な定義は何ですか」

もしそうなら、私はあなたが運が悪いと思う-「抽象化」はソフトウェアアーキテクチャ/設計用語であり、私が知っている限り数学的な裏付けがないここで)、「結合」または「情報隠蔽」以上は数学的な定義を持っています。


2

抽象化とは、関連すると思われる詳細を無視して、関連すると見なされる詳細を優先する場合です。

抽象化には、カプセル化、情報の隠蔽、一般化が含まれます。類推、比phor、またはヒューリスティックは含まれません。

抽象化の概念の数学的形式はそれ自体抽象化になります。これは、基礎となるものを数学的なプロパティのセットに抽象化する必要があるためです。のカテゴリー理論の概念は、おそらくあなたが探しているものに最も近いでしょう。

抽象化はあなたが宣言するものではなく、あなたがすることです


+1、「抽象化する!」Tシャツのための素晴らしいだろう。それは直接言及していないのに())射(S上のリンクのおかげで、ポリ -ダースとりわけ1を述べた;))も。
mlvljr

2

他の人にそれを説明する方法として、私は逆に結果から戻って行きます:

コンピュータプログラミングの抽象化とは、複数の類似したものを一般に同じものとして扱い、同じように処理できるように、何かを一般化する行為です。

それを拡張したい場合は、以下を追加できます:

これは、多態的な動作(インターフェイスと継承)を実現して繰り返しコードを事前に削減するために行われることもあれば、何かの内部動作を将来の日付で変更せずに同様のソリューションで置き換えることができるように行われることもあります抽象化されたコンテナまたはラッパーの反対側のコード。将来の手直しを減らすことを願っています。

それを超えて、あなたは例から始めなければならないと思います...


1

Bob Martinのメトリックスのいくつかを確認することをお勧めします。

http://en.wikipedia.org/wiki/Software_package_metrics

とはいえ、彼の「抽象性」はあなたのものと同じだとは思いません。彼は、インターフェース/抽象クラスの使用を意味する「クラスでの実装の欠如」の尺度です。不安定性とメインシーケンスからの距離は、おそらくあなたが探しているものにより深く関わっています。


ええ、その紙を覚えています。ボブおじさんは、群衆を元気づけ、人々にオブジェクト指向の仕組みに興味を持たせるのが素晴らしい。
mlvljr

不思議なことに、私は(一度に)
投票

1

Merriam-websterは、abstractを形容詞として定義します:特定のインスタンスからの関連付けを解除します。

抽象化は、何らかのシステムのモデルです。それらはしばしば、実際のシステムが抽象化によってモデル化されるために満たされなければならない仮定のグループをリストし、ますます複雑になるシステムを概念化するために使用されます。実際のシステムから抽象化に移行するための正式な数学的方法はありません。それは、抽象化を定義している人の判断と、抽象化の目的は次第です。

ただし、多くの場合、抽象化は数学的構造の観点から定義されます。これはおそらく、それらが科学や工学で非常に頻繁に使用されているためです。

例は、ニュートン力学です。すべてが無限に小さく、すべてのエネルギーが保存されていると仮定します。オブジェクト間の相互作用は、数式によって明確に定義されます。今、私たちが知っているように、宇宙はそのようにはまったく機能せず、多くの状況で抽象化が漏れます。しかし、多くの状況では、非常にうまく機能します。

別の抽象的なモデルは、典型的な線形回路要素、抵抗、コンデンサ、およびインダクタです。繰り返しますが、相互作用は数式によって明確に定義されます。低周波回路、または単純なリレードライバーなどの場合、RLC分析はうまく機能し、非常に良い結果を提供します。しかし、マイクロ波無線回路のような他の状況では、要素が大きすぎ、相互作用はより細かく、単純なRLC抽象化は持ちこたえません。その時点で何をするかは、エンジニアの判断次第です。他のエンジニアの上に別の抽象概念を作成したエンジニアもいれば、理想的なオペアンプを動作方法の新しい数式に置き換えたり、理想的なオペアンプをシミュレートされた実際のオペアンプに置き換えたり、小規模な複雑なネットワークでシミュレートしたりします理想的な要素。

他の人が言ったように、それは単純化されたモデルです。複雑なシステムをよりよく理解するために使用されるツールです。


私はおそらくこれをもっと強調すべきだったでしょうが、実世界のプロトタイプの不必要な詳細を欠いているような抽象化には興味がありません。 (例は、ビジネスアプリケーションで役立つ可能性がある実際のEmployeeのプロパティを使用してEmployeeクラスを構築することです)。私が興味を持っているのは、それを扱う他のそのようなエンティティからソフトウェアエンティティを「壁」にする一種の抽象化です(例はEmployerの仮定ですEmployee)。
mlvljr

1
意味がありません。実際のシステムの設計に関するヒントを提供することは、抽象化の目的ではありません。モデル化されているものについて何も知らない場合、それは抽象化が解決するための問題ではありません。
-whatsisname

ソフトウェアを作成する過程で、ソフトウェアが扱う実世界のオブジェクトの詳細を抽象化することについて話していました。現実世界のエンティティの(ソフトウェア)抽象化を使用して、現実世界のものを(再)設計することは意味していません(「システム」としての「ソフトウェアシステム」ですが、「システムの設計に関する有用なヒントを提供する」上記の私のコメント)。
mlvljr

1

抽象化とは、何か(概念、データ構造、関数など)を他の何かに関して表現していることです。たとえば、言葉を使ってコミュニケーションを図ります。単語は抽象的な要素であり、音で表現する(音声)か、グラフィカルシンボルで表現する(書く)ことができます。抽象化の重要な考え方は、単語がそれを発するために使用される音やそれを書くために使用される文字ではないのと同様に、問題のエンティティは基礎となる表現とは異なるということです。

したがって、少なくとも理論的には、抽象化の基礎となる表現を別の表現に置き換えることができます。ただし、実際には、抽象化は基本となる表現と完全に区別されることはめったになく、表現が「漏れる」こともあります。たとえば、スピーチには感情的な低音が含まれており、書くことは非常に困難です。このため、同じ単語の音声録音と書き起こしは、視聴者に非常に異なる影響を与える可能性があります。言い換えれば、言葉の抽象化はしばしば漏れます。

抽象化は通常、レイヤーで行われます。単語は文字で表すことができる抽象化であり、文字はそれ自体が音の抽象化であり、それはまた、声帯によって作成され、鼓で検出される空気の粒子の動きのパターンの抽象化です。

コンピューターサイエンスでは、ビットは通常、表現の最低レベルです。バイト、メモリ位置、アセンブリ命令、およびCPUレジスタは、次のレベルの抽象化です。次に、バイト、メモリの場所、およびアセンブリ命令の観点から実装された、高レベル言語のプリミティブデータ型と命令があります。次に、プリミティブデータ型の観点から実装され、言語命令に組み込まれている関数とクラス(オブジェクト指向言語を想定)。次に、より複雑な関数とクラスが、より単純なものに関して実装されます。これらの関数とクラスの一部は、リスト、スタック、キューなどのデータ構造を実装します。これらは、プロセスのキュー、従業員のリスト、または書籍名のハッシュテーブルなどのより具体的なエンティティを表すために使用されます。


1
それが漏れやすい場合、それは明らかに抽象化ではありません...十分、正直にしましょう。
mlvljr

2
@mlvljrコンピュータは残念ながら数学の問題ではないので、ある程度のリークを許容する必要があります。それ以外の場合は、物理デバイスで計算が実行されているという事実は、モデル化できる問題の範囲に対する特定の制約を意味します。技術的には、不完全性定理は、内部的に数学システムについて特定のことを証明できないことを意味するため、数学でさえ「漏れやすい抽象化」を持っています。
CodexArcanum

2
抽象化が漏れる状況を常に見つけることができます。完全な抽象化などはありません。それは、どれだけ漏れるか、それとともに生きることができるかどうかの問題です。
ディマ

@CodexArcanum 1. int(MAX_INT_SIZE / 2-1)より小さい値を取り、2倍の別の値を返すルーチン。2. ... uhmmに従って呼び出される必要があるときに呼び出されるint f(int a) { return a*2; }プロトタイプvoid (*) (void)を持つ「ハンドラ」呼び出し元のコントラクト-両方とも抽象化を表します(1-その実装の詳細(提供しましたが、ソースコードにアクセスできない人にはアクセスできません)、2-ハンドラー(ただし、これはハンドラを割り当てた人に知られていることに注意してください)、リークしない
mlvljr

MAX_INT_SIZEの制限は、メソッドのシグネチャのどこにも明確化されていません。コントラクトベースのプログラミングを可能にする言語(Eiffelなど)を使用しない限り、リークです。文書はシステムの外部にあるため、文書の制限に言及することは考慮されません。また、操作の途中で電源が切れた場合はどうなりますか?ネットワーク経由でデータを送信する必要があり、遅延がある場合はどうなりますか?システムのハードウェアの物理性を抽象化するプログラミングパラダイムはありません。
CodexArcanum

1

私が人々にそれを説明しようとする一つの方法は、最良の方法ではないかもしれません

2 + 2を追加して4を出力するプログラムを考えます

ユーザーが入力した2つの数値x + y = zを追加するプログラムを考えます

どちらがより便利で一般的ですか?


ケイトグレゴリーの答えに対する私のコメントはほぼそれでした。;)おもしろいのは、あまり一般的ではないプログラムはより一般的なプログラムを利用できるが、最初のプログラムに2番目のプログラムを要求したユーザーに提供することはおそらく逆に役立つことです
...-mlvljr

1

抽象化は不必要な詳細を隠すものだと私は主張します。抽象化の最も基本的な単位の1つは手順です。たとえば、ファイルからデータを読み取るときに、データベースにデータを保存する方法について心配する必要はありません。そこで、save_to_database関数を作成します。

抽象化を結合して、より大きな抽象化を形成することもできます。たとえば、関数をクラスにまとめたり、クラスをまとめてプログラムを作成したり、プログラムをまとめて分散システムを作成したりできます。


/が必要な実装を選択しているのでsave_to_database、コードの呼び出しは/が保存されている限り、データが正確に保存されることを心配するべきではありません!すなわち、とにかく(一部のコードに対して「抽象化された」抽象化された)詳細を提供する場所があるでしょう、それは賢明にそれを選ぶことの問題です-より簡単な「心の変化」などを提供する
-mlvljr

1

プログラミングの抽象化は、細部を隠し、簡素化されたインターフェイスを提供するものだと常に考えています。これは、プログラマが記念碑的なタスクを管理しやすい部分に分解できる主な理由です。抽象化により、すべてのざらざらした詳細を含む問題の一部に対するソリューションを作成し、ソリューションを使用するためのシンプルなインターフェイスを提供できます。その後、実質的に詳細を「忘れる」ことができます。これは非常に重要です。なぜなら、人は超複雑なシステムの詳細をすべて一度に心に留めることができないからです。これは、抽象化の下にある詳細を再検討する必要がないと言うことではありませんが、当面は、インターフェイスのみを覚えておく必要があります。

プログラミングでは、この単純化されたインターフェイスは、変数(ビットのグループを抽象化し、より単純な数学的インターフェイスを提供する)からクラス(以降、単一行呼び出しへの処理量を抽象化する)に至るまで、あらゆるものです。

最終的に、プログラマーの主な仕事は、通常、すべての計算の詳細を抽象化し、コンピューターの動作方法を知らない人が利用できるGUIのようなシンプルなインターフェイスを提供することです。

抽象化の利点のいくつかは次のとおりです。

  • 大きな問題を管理しやすい部分に分割できます。人のレコードをデータベースに追加する場合、データベースにインデックスツリーを挿入してバランスを調整する必要はありません。この作業はある時点で行われた可能性がありますが、現在は抽象化されており、もはや心配する必要はありません。

  • プロジェクトで複数の人が一緒にうまく働くことができます。私は同僚のコードのすべての詳細を知る必要はありません。私はちょうどそれを使用する方法、それが何をするのか、そしてそれを私の仕事(インターフェース)と合わせる方法を知りたいのです。

  • 必要な知識を持っていない人でも、複雑なタスクを実行できます。私の母は彼女のフェイスブックを更新することができ、彼女が全国に知っている人はそれを見ることができます。非常に複雑なシステムを単純なWebインターフェースに抽象化しないと、彼女が同様のことを始めることができません(私もそういうことはできません)。

ただし、抽象化は、使いすぎると物事を管理しにくくするという逆の効果があります。問題を細かく分割しすぎると、覚えておく必要のあるインターフェイスの数が増え、実際に何が起こっているのかを理解するのが難しくなります。ほとんどのものと同様に、バランスを見つける必要があります。


1

間接レベルの追加レベル。

使用しているオブジェクトがa Catかa かを気にしたくないDogので、仮想関数テーブルを調べて適切なmakeNoise()関数を見つけます。

私は確かにこれは同様に「低」と「高」レベルにも適用することができるんだ-指定したプロセッサやHaskellのために使用する権利命令を見上げコンパイラを考えるMonadすべてのものを呼び出すことによって、計算の効果の上に抽象化秒returnとします>>=


1

これは私が実際にもっと長い間ブログに書きたいと思ったものですが、私は決してそれに着きませんでした。幸いなことに、私は担当者ゾンビであり、賞金さえあります。私の投稿はかなり長いことが判明しましたが、ここに本質があります:

プログラミングの抽象化とは、特定のコンテキスト内のオブジェクトの本質を理解することです。

[...]

抽象化は一般化だけでなく、カプセル化とも誤解されますが、これらは情報隠蔽の2つの直交部分です:サービスモジュールは表示する内容を決定し、クライアントモジュールは表示する内容を決定します。カプセル化は最初の部分であり、抽象化は後者です。両方が完全な情報隠蔽を構成します。

お役に立てば幸いです。


+1、ええ、トピックは本当に私たちの多くをつまらないようです;)私は(最終的に)自分のいくつかのポイントであなたの答えを補完して、議論にさらに興味を起こさせたいと思います。
mlvljr

0

ここで、非数学的な答え:

プログラミングをやめることは、今は詳細を気にしないふりをしているのに対して、実際にはあなたは詳細を気にしなければならないのです。基本的にふりをしています。


1
+1、しかし常にそうとは限りません(本当に不必要な詳細を考えてください:) 最初の質問は、「詳細を永久に削除するか、一時的に忘れるか、それを知らない何らかの方法で利用することですか?」です。
mlvljr

1
今日、顧客に何個の光子が当たったかは気にしません。
flamingpenguin

0

私にとって抽象化は「文字通り」存在しないものであり、アイデアのようなものです。あなたが数学的にそれを表現するなら、数学はあなたの脳で起こることを表現する言語であり、他の誰かの脳が理解できるので、もはや抽象的ではありません。もう、アイデアモデルを表現するには、脳がどのように機能するかを理解する必要があります。

抽象化は、現実をそれとは独立した何かに解釈できるようにするものです。ビーチと夢を抽象化できますが、ビーチは存在しますが、夢は存在しません。しかし、あなたは両方が存在することを伝えることができますが、それは真実ではありません。

抽象化で最も難しいのは、他の人が理解できるように表現する方法を見つけることです。それは最も困難な仕事であり、それを実際に単独で行うことはできません。自分のアイデアで機能し、他の誰かが理解できる相対モデルを発明する必要があります。

私にとって、コンピューター言語での抽象化とは、モデルを「数学化」するという名前であり、伝達できるアイデアを再利用することであり、抽象的に達成できるものと比較すると大きな制約です。

簡単に言うと、原子は互いに隣接していますが、それらは気にしません。人間に組織化された多数の分子は、彼が誰かの隣にいることを理解できますが、それがどのように原子自体が何らかのパターンに配置されたかだけでは理解できません。

概念によって支配されるオブジェクトの1つは、一般に、それ自体を「理解」することはできません。それが私たちが神を信じようとする理由であり、私たちが脳を理解するのに苦労している理由です。

メダルをもらえますか?


0

興味深い質問。プログラミングに関して、権威あると見なされる抽象化の単一の定義を知りません。他の人々は、CS理論または数学のさまざまな分野からのいくつかの定義へのリンクを提供していますが、「supervenience」と同様の方法で考えるのが好きですhttp://en.wikipedia.org/wiki/Supervenienceを参照してください

プログラミングの抽象化について話すとき、本質的にはシステムの2つの記述を比較しています。コードはプログラムの説明です。コードの抽象化は、そのプログラムを「より高い」レベルで記述することにもなります。もちろん、元の抽象化をさらに高いレベルで抽象化することもできます(たとえば、高レベルのシステムアーキテクチャでのプログラムの説明と、詳細設計でのプログラムの説明)。

ここで、ある記述を別の記述よりも「高レベル」にするもの。重要なのは「複数の実現可能性」です。プログラムの抽象化は、多くの言語でさまざまな方法で実現できます。1つのプログラムに対して複数のデザインを作成することもできます。2人でプログラムを正確に記述する2つの異なる高レベルデザインを作成できます。実現の等価性が違いを生みます。

プログラムまたは設計を比較するときは、そのレベルで説明の主要なプロパティを識別できる方法で行う必要があります。設計が別の設計と同等であると言う複雑な方法に入ることができますが、それについて考える最も簡単な方法はこれです-単一のバイナリプログラムは両方の記述の制約を満たすことができますか?

では、あるレベルの記述を他のレベルよりも高くするのはなぜですか?あるレベルの説明A(例:設計文書)と別のレベルの説明B(例:ソースコード)があるとします。AがBよりも高いレベルであるのは、A1とA2がレベルAで2つの非等価な記述である場合、それらの記述の実現、B1とB2 もレベルBで非等価でなければならないためです。ただし、逆は必ずしも成り立たない。

したがって、2つの異なる設計ドキュメントを満たす単一のバイナリプログラムを作成できない場合(つまり、それらの設計の制約が互いに矛盾する場合)、それらの設計を実装するソースコードは異なる必要があります。しかし一方で、同じバイナリプログラムにコンパイルできない可能性のある2つのソースコードセットを取得した場合、これらの2つのソースコードセットをコンパイルした結果のバイナリは両方とも同じ設計を満たす可能性があります資料。したがって、設計ドキュメントはソースコードの「抽象化」です。


0

プログラミングの抽象化とは、誰かがプログラムの要素に対して行う抽象化です。アイテムやアイテムでメニューを作成する方法を知っているとしましょう。次に、誰かがそのコードを見て、他の種類のハイリーチのような構造で役立つ可能性があると考え、最初のコードの抽象化であるコンポーネントデザインパターンを定義しました。

オブジェクト指向設計パターンは抽象化の非常に良い例であり、実際の実装を意味するのではなく、ソリューションにアプローチする方法を意味します。

要約すると、プログラミングの抽象化は問題を理解するためのアプローチです。それは何かを得る手段ですが、それは本物ではありません

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