皆さんはプログラミングをする際にどのようなことを意識していますか?
これまでの歴史の中では、様々なプログラミングの考え方やスタイルが生まれてきました。
こういったものはプログラミングパラダイムと呼ばれ、エンジニアにとっては欠かせない重要な知識となります。

プログラミングのベストプラクティスを知るには、どのようなスタイルに従ってプログラムを書けばよいかを学ぶ必要があります。

未経験からプログラミングを始めてみたいなら、まずは無料相談!
案件の取り方から就職・転職のキャリア相談、面接練習までできるのでおすすめです。
新規無料相談はこちらから【ZeroPlus】

プログラミングパラダイムとは

プログラミングパラダイム(または単にパラダイム)は、プログラムを書く時の考え方やルール、スタイルなどの「規範」のことです。
あるタスクに対してそれを解決する方法はひとつとは限りません。
むしろそうでない場合の方が多いでしょう。

どのような考え方でタスクを解決するのか、それがパラダイムです。
パラダイムには様々な種類があり、言語によっても対応するパラダイムが異なります。

大きく分類すると、命令型宣言型の2種類があります。
またオブジェクト指向であるか、そうでないか、といった視点でも分類することができます。

スコープとは

プログラミングパラダイムの分類を見ていく前に、プログラミングにおいて重要となるスコープについてご紹介します。

スコープとは、プログラムの中で扱われてるデータ(変数、オブジェクトなど)をどこから参照できるか、という概念のことです。
これはデータが使用可能な範囲を指しており、スコープの外からデータを取得したり変更したりすることはできません。

プログラムのどこからでも参照できるデータはグローバルスコープといいます。
一方で限られた範囲内でのみ扱われるデータはローカルスコープといいます。

スコープはできるだけ限定しておくことが理想的です。
これは、データが想定しない場所から書き換えられると、どこでデータが変更されているのかわからないといった事態が起こりやすくなるからです。

スコープが広くなればなるほどデータが変更される可能性のある領域が増え、予期せぬエラーにつながります。
そうなると保守性・メンテナンス性が損なわれ、質の悪いコードになってしまいます。
ということでプログラムを実装する際は、グローバルスコープに依存しすぎずなるべくローカルスコープのデータを扱うようにするのが理想的です。

実際、様々なプログラミングパラダイムが生まれてきた背景にもこのスコープの問題は大きく関わっています。

また、プログラムが動いているときのデータの状態のことをステートといいます。
グローバルスコープを持つデータはグローバルステートである、と言えます。

今すぐWeb業界で活躍したいなら、エンジニアの無料相談を受けてみませんか?
開発現場が求めるレベルのプログラミングスキルを身につけ、就活に強いポートフォリオを作成しましょう!
エンジニア発オンラインスクール【RUNTEQ】

命令型(手続き型)プログラミング

このパラダイムでは、命令や手続きを組み合わせることでタスクを解決します。
手続きは各プログラミング言語によって関数、プロシージャ、サブルーチン、メソッドなど様々な呼び方がされています。
命令のかたまりである手続きを作っておくことで、プログラムの再利用性を向上させています。
これをモジュール化といい、最終的なコードの量を大幅に減らすことができます。

また、処理の流れがわかりやすいためプログラムのチューニングがしやすいという利点があります。
一般的によく使われる言語の多くがこの命令型プログラミングに分類されます。

このパラダイムでは、連続した手続きの中で変数やデータの状態(ステート)を変化させていき、少しずつ望んだ結果に近づけていきます

プログラムが予期せずグローバル変数の状態を変えてしまう問題のことを副作用といいます。
手続き型プログラミングでは、この副作用が起こりやすいのが欠点となっています。
プログラムの肥大化によってグローバル変数の数が増え、維持管理が難しくなっていくのです。

また、命令型のパラダイムは構造化プログラムであるという特徴があります。
構造化プログラムとは、順接・分岐・反復の3つの制御構造を組み合わせて構成されたプログラムを指します。

順接とはプログラムが上から順番に実行されていく構造のことです。
分岐とは条件に応じてプログラムが実行する処理を変化させる構造(if文、case文)のことです。
反復とは特定の手続きを複数回実行する構造(while文、for文)のことです。

宣言型プログラミング

こちらは命令型プログラミングと対照的なパラダイムです。
処理の手順を記述するのではなく、解決したいタスクの性質や意味、制約を記述します。

宣言型には、プログラムの一部を取り出したときにそれが意味を持つという特徴があります。
これは、プログラムの一部を削除しても全体として意味を失わない、ということにもなります。
逆に言えば命令型プログラミングではプログラムの一部を取り出してもその部分だけでは意味をなさない場合が多いです。
もっと言うと、命令型の設計思想はそれだけ汎用的であるとも言えます。

宣言型、命令型はそれぞれに利点・欠点があり、どちらが優れているとは言い切れません。
用途や目的によって的確にパラダイムを選択できるように、どのような考え方が存在しているのかをしっておきましょう。

宣言型プログラミングは以下のように、さらにいくつかのパラダイムに分類することができます。

関数型プログラミング

関数の組み合わせによって目的を達成するプログラミングパラダイムです。
命令型プログラミングとは違い、データがステートを持ちません。
プログラムの状態を変化させない関数(純粋関数)により処理を行っていくことから、副作用が生じないという大きなメリットがあります。

関数型プログラミングはある関数の戻り値を次の関数に渡してつなげていくツリー構造になっています。
プログラムがシンプルになり、理解しやすいのがメリットです。

一方でグローバルステートを利用した処理が扱えないので、実装しにくい機能にぶつかることもあります。
また、コンピュータが実際に処理する命令が見えづらいため、パフォーマンスチューニングが難しくなります。

関数型プログラミング言語にはScala、Haskellなどがあります。

論理型プログラミング

論理式を組み合わせてタスクを解決する、という考え方です。
データ同士の関係性を定義し、事実・規則・質問の3つの要素で構成されています。

主に人工知能(AI)に活用されており、数学的手法で記述されているのが特徴です。
事実と規則でプログラムを積み上げていき、質問を与えることで処理を実行させて結果を得ることができます。
自ら立てた仮説に対して結論を導いていく帰納的なプログラムとなっています。

代表的な論理型プログラミング言語は、Prologです。

制約プログラミング

いくつかの制約条件を宣言しておき、それらを満たす答えを導くための方法を記述するプログラミングパラダイムです。

複雑な条件を含む多種多様なタスクに対して幅広く活用されます。
情報の関係性が双方向に定義されており、オブジェクト指向プログラミングとの親和性が高いです。

宣言的であることから、プログラムを見ただけでは挙動がわかりにくいのが欠点です。

オブジェクト指向プログラミング

オブジェクト指向プログラミングは、非常に多くの言語で取り入れらているパラダイムです。
関数や変数をひとつにまとめたオブジェクトというものを考えます。
プログラムを手順ではなくこのようなオブジェクトの操作としてとらえるのがこの考え方です。

プログラムの対象となるものを抽象化し、システムを単純な構造にすることが目的です。
オブジェクトのテンプレートとなるクラスを定義しておき、クラスからインスタンスを生成、生成したオブジェクトを操作していく、という流れでプログラムを記述します。

オブジェクト指向では特有の単語がたくさん出てきて混乱しやすいので、整理しておきます。
ここでは一部、ネコを例に説明を進めていきます。

クラス

クラスあるオブジェクトの一般的な動作や特性をまとめて定義した雛形(設計図)のようなものです。

例えば「ネコ」クラスには「走る」「獲物を追いかける」「鳴く」といった動作や、「名前」「体重」「毛の模様」などの特性を定義したりします。
つまり、ネコというオブジェクトの特性を一般化したものということになります。

インスタンス(オブジェクト)

インスタンスとは、クラスから生み出された具体的なオブジェクトの実体です。
クラスが一般的な概念を定義したものであるのに対して、インスタンスは固有の特徴を持ちます。

「ネコ」クラスを元に、「タマ」や「モモ」といった具体的な一匹のネコのインスタンスを生成したりします。
それぞれのインスタンスは他のインスタンスに影響を受けない固有の特性値を持ちます。
「タマ」という「ネコ」クラスのインスタンスは体重が4kgなのに対して、「モモ」は同じ「ネコ」クラスのインスタンスであっても体重は3kgである、といった具合です。

プロパティ

プロパティとはクラス内で定義されるオブジェクトの特性値のことです。
プロパティの存在により、同じクラスから生成されたオブジェクトでも様々な情報や特徴を持たせることができます。

例としては「ネコ」オブジェクトの「名前」「体重」「毛の模様」といった特性を表す値を指します。

メソッド

メソッドとはクラス内で定義される関数のことです。
インスタンスからメソッドを呼び出すことで処理を実行することができます。

メソッドには「ネコ」オブジェクトの 「走る」「獲物を追いかける」「鳴く」 といった動作が、具体的にどのような処理によって成り立っているかが定義されています。

パラメータ(引数)

パラメータはクラスのメソッドを実行するときに、メソッドに対して与える値のことです。
通常の関数における引数と同じ意味です。
関数の処理内容を補足するような値で、パラメータに応じてメソッドの実行結果が変化します。

リターン(戻り値)

リターンはメソッドの実行結果として返却される値です。
通常の関数における戻り値と同じ意味なので、単純に戻り値と呼ばれることの方が多いかもしれません。

コンストラクタ(イニシャライザ)

コンストラクタインスタンスを生成する際に最初に実行されるメソッドです。
インスタンスに対する初期化を行い、プロパティの初期値を設定したりするのが一般的です。

例えば「ネコ」クラスから「タマ」というインスタンスを生成する際に、初期値として「毛の色」や「体重」といったプロパティを登録するというイメージです。

インヘリタンス(継承)

インヘリタンスとは、あるクラスがその親となるクラスの特性を受け継ぐ性質のことです。
子クラスは親クラスが持つメソッドやプロパティを持っています。
さらに継承した親クラスのメソッドを上書きすることもでき、これを(メソッド)オーバライドといいます。

例として「生物」クラスを親に持つ「ネコ」クラスを定義するとします。
これは基本的には「生物」クラスとしての特徴を持っているのですが、このクラスにだけ適用される限定的なメソッドやプロパティを定義することもできます。

抽象クラス・具象クラス

上書きされることを前提とした、インスタンスを生成することができないクラス抽象クラスといいます。
また、実際にインスタンスを生成することを目的として抽象クラスを継承したもの具象クラスといいます。
抽象クラスを親クラスとしてインヘリテンスした子クラスが具象クラスになります。

抽象クラスは、具象クラスに対して指定したメソッドを持つことを強制することができます。

ここでは「ネコ」クラスの親クラスとして「生物」クラスが存在しているとします。
「生物」クラスはすべての子クラスに対して、「鳴く」というメソッドを持つことを強要しています。
「ネコ」クラスではこれをオーバーライドして、”ニャー”という戻り値を持ったメソッドを定義します。

具象クラスは抽象クラスを多重継承することはできません。
例えば「生物」の子クラスでありながら、同時に「無機物」の子クラスであることはできないことを意味します。

インタフェース

インタフェースを使うと、異なる抽象クラスを持つ具象クラスに対しても同じメソッドを持たせることができます。
親子関係にあるクラスの継承以外の方法で共通のメソッドを定義する方法として有効です。
少しわかりにくいですが、抽象クラスはクラスの内部からメソッドを強制したのに対し、インタフェースではクラスの外部から強制しています。

また、抽象クラスとは異なりこちらは複数のインタフェースを多重継承できます。
インタフェースの概念は少しわかりにくいですが、クラスに対して特定のメソッドを持つように約束をしていると考えればよいでしょう。

カプセル化

カプセル化とは、オブジェクト指向においてデータをクラスの内部からしかアクセスできないようにした性質のことです。
これによりデータを隠蔽・保護しており、クラスの実体が外から見えないようにしています。

ポリモーフィズム

ポリモーフィズムは、異なるクラスのオブジェクトによって同じ名前のメソッドでも別々の処理を実装できる性質のことです。

例えば「生物」クラスの子クラスとして、「ネコ」クラスのほかに「イヌ」クラスがあるとします。
「ネコ」クラスでは「鳴く」メソッドをオーバーライドして戻り値を”ニャー”に、「イヌ」クラスでは同様に「鳴く」メソッドの戻り値を”ワン”にします。

すると一見同じに見える「鳴く」というメソッドが、オブジェクトごとに異なる処理として実行できるようになります。
これがポリモーフィズムの性質です。

未経験からITエンジニアを目指したい方の特化型就職サポートはこちらからカウンセリングを受けてみませんか?
希望に応じて学習のサポートも完全無料で受けられるお得なサービスです。
ITエンジニア就職に特化した【ウズキャリIT】

マルチパラダイム言語とは

プログラミング言語の中にはマルチパラダイム言語と呼ばれ複数のパラダイムに属する言語もあります。
これは複数の特性を持つ柔軟な言語ということであり、問題解決のための最良の方法をプログラマ自身が考える必要があります。

JavaScript、C++、C#、Scalaなどはマルチパラダイム言語に分類されます。

まとめ

今回はプログラミングパラダイムについて見てきました。
タスクを解決するために様々なスタイルがあることがわかりましたね。

自分が解決したいタスクに対してどのパラダイムを使えばいいのか選択できるようになれば、プログラムの幅が広がります。
特に命令型やオブジェクト指向は多くの言語で取り入れられているパラダイムになるので、しっかり理解しておきたいですね。

ひとりではなかなかプログラミングの学習が続かない、未経験だから不安が多い、という方はプログラミングスクールを利用してみるのも有効です。
本物のエンジニアに学ぶことで、時間がない方でも最短でスキルを身につけることができます。
現役エンジニアのパーソナルメンターからマンツーマンで学べる

お悩みの方は、まずは無料キャリアカウンセリングにお申込みください。

関連記事

この記事のタグ