私は Java で非常にオブジェクト指向(OO)スタイルでプログラミングしています。 OOPは非常に直感的に理解できますが、他の種類のプログラミングについてはほとんど知識がありません。
手続き型プログラミングとは正確には何ですか?それはOOPとどのくらい正確に異なりますか? 関数型プログラミングと同じですか?
オブジェクト指向ではないプログラミングはすべて手続き型だと思っていましたが、私はそうです。 mこれは真実ではないと考え始めています。
コメント
回答
ウィキペディアには、これらの用語についての適切な説明があります。とにかく、ここに要約があります:
- 命令型プログラミング は、可変状態を変更する一連のステートメントとして計算をモデル化します。
- 手続き型プログラミング は、コードをサブルーチンに分解する命令型プログラミングです。
- 構造化プログラミング は、任意のジャンプを禁止する手続き型プログラミングへのより統制のとれたアプローチです。 (例:goto)およびグローバル状態の変更。
-
宣言型プログラミング は、命令型プログラミングの反対であり、方法ではなく計算対象を指定します(SQL、regexesなど)。
-
関数型プログラムming は、計算を式としてモデル化し、値を生成します(可能性があります)。関数は値であり、他の関数との間で受け渡しまたは返すことができます。突然変異は推奨されません。デフォルトでは、すべての変数は不変です。結果として、それを達成するために必要な状態変化のシーケンスではなく、計算されているものを強調するため、必須よりも宣言的です。
- 純粋に関数型プログラミング は、突然変異を完全に禁止します(ただし、一般的な信念に反して、側面を達成するためのメカニズムはまだあります効果)。
- 関数型プログラミングの合計 はさらに、例外と無限ループを禁止します(数学の全関数は、その入力のすべての値を返す関数です。)
- オブジェクト指向プログラミング は、 オブジェクト/インターフェースを使用して抽象化とモジュール性を実現します。
OOPはかなりロードされた用語。オブジェクトは関数型言語と手続き型言語の両方で使用できますが、OOとしてアドバタイズする言語は手続き型です。問題をさらに混乱させるには:
- ほとんどの人はオブジェクトと抽象データ型の違いを知りません
- 主流のOOP言語は、ADTについて言及しておらず、ADTのサポートが非常に貧弱であり、オブジェクトを1つの真の方法として宣伝しています。
- 抽象データ型指向プログラミング / em>(これはばかげたことなので、ADTとオブジェクトの両方が必要です。)
これにより、人々はOOPが抽象化を実現する唯一の方法であると考えます。機能プログラミングとOOPは、どういうわけか反対であるか、相互に排他的です。多くの人々はまた、すべての関数型言語は純粋であり、突然変異を許可しないと考えています。
さらに、人々は一般に命令型/手続き型を交換可能に使用し、OOP(抽象化のないコード、一般的にはCを意味する)と対比することもあります。関数型プログラミングとは対照的です。構造化プログラミングという用語は、私が知る限りほとんど使用されていません(この時点で、ほとんどの人がgotoとグローバルが有害であると考えているのは当然だと考えているためです)。
コメント
- "ジャンプを禁止"はかなり一般的です。これには、if / while / etcが含まれます。おそらく"任意のジャンプを禁止します"?
- @Izkata良い点、変更されました。
- 実際にウィキペディアのエントリにリンクする価値があるかもしれません。
- そしてそれが'理由です'はオブジェクト"指向"と呼ばれ、オブジェクトのみではありません。
- @OrangeDogどうですかまたカプセル化されたデータのセットとそれに作用できる関数を定義する抽象データ型とは異なりますか?さらに、不変のオブジェクトを持つことができるので、その場合、どのような状態?
回答
手続き型プログラミングは、他の多くの言語設計の構成要素の1つであるプログラミングへのアプローチです(関数型は1つではありません)。
ほとんどの言語は、「手続き型プログラミング」のセットに分類されます。そして、それはおそらくほとんどの人にとって最も自然な設計アプローチです(OOの観点から考えると、私はあなたが少数派であると言います)。
BASICは手続き型です。
他の人が言っているように、これはプログラムを順番に構造化するためのメカニズムです。
- 最初にxを実行します
- 2番目にyを実行します
- 3番目にZを実行します
「プロシージャ」を定義するメカニズムが必要です。OOメソッドに似た名前付きコードのブロックで、0から多数のパラメータを受け入れ、オプションで値を返します(これはその場合、一般的に関数と呼ばれます-おそらく関数型言語との混乱につながります)
パラdigmは、実行する内容や渡される方法を指示するものではありません。
プログラムが、で動作する一連のプロシージャ(または関数)として構造化されることを説明するだけです。シーケンシャルな方法。次に、データはプロシージャとは独立して定義されます。
これは、データのコレクションとそのデータに作用するメソッド(関数ではない)を中心にプログラムを構築するオブジェクト指向プログラミングとは異なります。
それについて考える1つの方法は、データスコープの観点からです。
手続き型言語では、スコープはかなり単純です。変数は、(ローカルで宣言された)特定のプロシージャのスコープ内にあり、(グローバルに宣言された)最上位のもののレベルまで、ネストされたスコープが間にあります。
オブジェクト指向言語では上記に直交する、現在使用されているオブジェクトの新しいスコープコンテキストを追加します。
オブジェクト指向と比較して、手続き型を考える別の方法は、オブジェクト指向言語を検討することです。ここで、すべてのメソッドは静的として宣言する必要があります 。その結果、クラスを使用してプロシージャをグループ化できる手続き型言語が作成されます。
回答
手続き型プログラミングは関数型プログラミングではありません。
手続き型プログラミングとは、コンピューターのモデルを頭の中に機械として持っていて、それをどのように考えているかということです。のメモリ内のデータを変更します。したがって、最初にA
を値3に設定し、次に1を追加して、それをメモリ位置A
に再度保存します(前の値を上書きします) 。
関数型プログラミングでは、A
は3、B
はA + 1
次に、コンピュータにB
の計算方法を理解させます。 A
を定義したら、それは不変(変更なし)である必要があります 。Functionalを使用すると、最初に関数を渡すなどのこともできます。クラス値(関数は関数を引数として取ることができます)。
オブジェクト指向プログラミングは両方を組み合わせることが多く、両方に直交するようなものです。関数プログラミングを使用して不変オブジェクトを返すことができます。オブジェクトは、計算された値を返すメソッドを持つことができ、それを怠惰に行うことさえできます-それは機能的なオブジェクト指向プログラミングです。 「リポジトリ」(データベースの抽象バージョン)を表すオブジェクトを作成することもできます。リポジトリにあるものを「保存」して「取得」し、そのオブジェクトにその方法のすべての詳細を処理させることができます。これは基本的にオブジェクト指向の手続き型プログラミングです。
回答
OOPは、手続き型プログラミングの少し洗練された形式にすぎません。 、これも命令型プログラミングのより大きなファミリーに属しています。その主張の証拠は、多くのC#/ Javaプログラマーが「何かをする」傾向があり、次のような方法を好むということです。
void doThisAndThat(....) { ... do something ... }
つまり、たくさんのプログラムで構成されていますvoid-methods(以前は procedure (sic!)と呼ばれていました)と次のようなコードの組み合わせ:
doThis(); if (state is that) doSomethingElse(); doThat();
は完璧な手続き型プログラミングです。
コメント
- doThisAndThat(….)は、メソッドが複数のことを実行することを意味しますが、これは一般的には適切な方法ではありません。 JavaおよびC#開発者は、主に単一責任の原則を順守しています。あなたのアナロジーには欠陥があると思います。 objectmentor.com/resources/articles/srp.pdf
- @JohnKそれは良い習慣ではないことを私は知っています。しかし、一般的なものです。特にJava開発者の間では、SOで毎日目にするもので判断できるかどうか。
- @JohnK JavaおよびC#開発者は、ほとんどが単一責任の原則に準拠しています-リップサービス?
- Java開発者は主に単一責任を順守しますか?それが現実の世界に当てはまるのなら…
も参照してください。