オブジェクト指向型や手続き型のようなプログラムの見方・考え方の枠組みのことをプログラミングパラダイムといいます。

実はプログラミングパラダイム周辺の議論において、これらの用語の定義は人によって異なっており一概に決められるものではありません。

その点も含めた上で一般的に共通している定義や特徴を整理し、メリットとデメリットの確認を行います。

  • 構造化プログラミング
  • 宣言型プログラミング
  • イベント駆動型プログラミング
  • スタック指向プログラミング
  • コンポーネント指向プログラミング

有名無名の様々なプログラミングパラダイムが存在しますが、本記事ではPythonで実現可能なパラダイムに絞り説明を行いましょう。

特に手続き型言語とオブジェクト指向言語について、メリットやデメリットの比較を行いながら詳しく解説を行います。

手続き型言語とは



手続き型言語の定義を確認しましょう。例え話としてカレーの料理レシピで考えてみます。

手続き型(Procedural)言語は個々のプログラムを手続き単位で記述し、最初から順番に処理をしていく言語です。

例えばカレーの作り方は上から順番に並んでいます。料理人は野菜を切る・肉を炒める・煮込むなどの調理を順を追って進めるでしょう。

また工程の1つひとつも突き詰めれば複数の手順の集まりです。

一口に肉を炒めるといっても「火を点ける・油を入れる・肉を入れる」などの複数の手順でできています。

このように複数の手順をまとめたものが、手続き型言語におけるモジュールです。

モジュールは他のモジュールを呼び出したり、逆に呼び出されたりしながら処理を進めていきます。

取り扱うデータは共通の場所に置いてあり、どのモジュールからでも参照が可能です。

代表的な他の手続き型プログラミング言語にはFortran・COBOL・BASICなどがあります。


手続き型言語のメリット



手続き型プログラミングのメリットは開発者にとって馴染みやすいところと、メモリ消費量が少ないところです。


コードが追いやすい

料理レシピの作り方のようなものなので、実装する開発者が行いたい処理を順番通りに書けばそれでプログラムになります。

後から処理を追いかける場合もどこで何をしているかが分かりやすく、全体としてどのような処理が行われているかが理解しやすいです。

料理レシピの作り方と料理人を見れば、今何番目の手順で何をしているかは一目で分かるでしょう。


学習難易度が低い



料理レシピ通りに作ることさえできれば、一流の料理人でなくても一定の質のカレーを作ることができます。

それは料理レシピの作り方が、誰が読んでも分かるように書かれているからに他なりません。

また手続き型ではオブジェクト指向のように複雑に考える必要はなく、行わせたい処理を指定された記法で頭から順番に書いていきます。

このため学習に必要なのは実行コマンドと文法規則くらいで、習得難易度が比較的低いです。


手続き型言語のデメリット



手続き型言語のデメリットは再利用性が低いこと、そして現実の物体と結び付かない扱いにくさでしょう。


再利用ができない

手続き型言語は手順の集まりだと説明しました。

カレー作りに必要な手順はポトフやシチューであれば再利用できるかもしれません。

しかし野菜炒めでは野菜の種類も切り方も変えなければいけませんし、肉巻きなら肉の種類や工程そのものも変わってきます。

プログラムであれば新しく別の手順の処理を書いて対応できますが、少しずつ内容の異なるモジュールが量産されることになるでしょう。

再利用性は決して高くありません。


グローバル



全てのモジュールで扱うデータは共通のものを使用しています。

このためあるモジュールに対して修正を行った場合は、以降の処理に影響がないかどうかも確認しなければなりません。

少しの修正がプログラム全体に影響することもあり、プログラムの追加・修正にコストがかかります。

例えば野菜を少し大きめに切るとしましょう。すると出来上がるのは火の通っていない具が入ったカレーになってしまうかもしれません。

今度は煮る時間を長くしてみましょう。今度はじゃがいもが溶けてなくなってしまいました。

このように全ての食材=データは関連しており、別のモジュールの修正が結果に影響を与えることがあるのがグローバルの怖いところです。


現実のモノと結び付かない

手順というモノは現実の世界には存在しません。道具や材料がこれに当てはまりますが、手順の中には表現されていないでしょう。

書くのも読むのも簡単ですが、後から出てくる要件の中には肉の種類を変えたいとか、野菜の切り方を変えたいといったものもあります。

それらを手続き型のプログラムの中に反映しようとすると、素直には結び付かないため慣れない方は混乱するでしょう。


オブジェクト指向言語とは



オブジェクト指向型(Object-oriented)言語は個々のプログラムをオブジェクト単位で記述します。

そしてオブジェクトが相互連携することで、プログラムを処理していくプログラミングパラダイムです。

例えば今度はキャンプでカレーを作ることを考えましょう。

指示を出したリーダーに、切った状態の野菜・焚き火の準備ができたことを告げます。

結果を受けたリーダーは、続いて煮込む役割を作り、空いている人に指示を出してカレー作りを続けてもらうでしょう。

このような1つひとつの役割がオブジェクトであり、指示を出すリーダーもまたオブジェクトの1つです。

代表的な他のオブジェクト指向プログラミング言語にはC++・C#・Javaなどがあります。


オブジェクト指向言語のメリット



オブジェクト指向のメリットは再利用性の高さと、現実のモノと結び付けて直感的に理解できる構造にあるでしょう。


再利用ができる

火を起こす役割の人は先の例で焚き火を作りました。焚き火はカレー作りだけでなく、魚を焼くのにもお湯を沸かすのにも使えます。

一定の火力さえあれば焚き火でなくてもいい筈です。

バーベキューコンロでもキャンプファイヤーでも、それらは間違いなく火を起こし提供するという役割を担うでしょう。

このようにオブジェクトは役割を持つ人でありモノであり、様々な場面で使い回すことができます。


カプセル化・継承・ポリモーフィズム

火の起こし方は火を起こす役割の人・モノが知っていれば良く、リーダーは指示の出し方と報告の受け取り方だけ知っていれば良いです。

また火は扱い方を間違えると危険なので、火の扱いに慣れた人だけが直接触れるようにするのが良いでしょう。

このようにオブジェクトの中身はできるだけ隠蔽し、メソッドや一部の変数のみを公開する手法がカプセル化です。

カプセル化によりオブジェクトの役割が明確になり、他オブジェクトと疎結合な関係になり、不用意にデータの書き換えがされなくなります。

カプセル化をはじめ継承・ポリモーフィズムなどは、オブジェクト指向プログラミングのメリット足り得る特徴です。


現実のモノと結び付く



オブジェクトは現実の人・モノと結び付けて考えることができます。手順と異なり実体があるのでイメージしやすいでしょう。

肉の種類を変えたければ豚肉を牛肉に変えれば良いだけです。

野菜の切り方を変えるには野菜を切る役割の人に、新しい切り方を覚えてもらえば良いということになります。

このように例え話との親和性も良いです。

オブジェクト指向言語のデメリット



オブジェクト指向プログラミングのデメリットは、コードの追いかけにくさと学習コストの高さにあります。


コードが追いかけにくい

今でこそデバッガやIDEが充実していますが、それでもオブジェクト指向型のプログラムを追いかけるのは大変です。

オブジェクトごとに役割が分かれているため、ステップ実行を行い様々なオブジェクトに飛びながらコードを追いかけます。

継承が複雑になればなるほどコードを読む側のスキルが必要です。

既存の別の誰かが書いたコードを修正するには、今まで知らなくて良かった役割の中身を知る必要があります。

どこまでコードを追いかける必要があるのか、どこまで知れば修正できるかの見当を付けるなど初心者には難しい技術でしょう。


学習難易度が高い



誤ったポリモーフィズムや継承もちらほら見かけます。オブジェクト指向プログラミングは一朝一夕に身に付く考え方ではありません。

手続き型プログラミングなど別の見方でやってきたという方は、オブジェクト指向型言語へのパラダイムシフトを求められるでしょう。

役割はどんどん抽象化することができます。焚き火から火へ、火から熱エネルギーへと原型を留めない概念だけの存在にもなるでしょう。

こうなると慣れている開発者でも理解するのに苦労します。


手続き型言語とオブジェクト指向言語の比較



手続き型言語とオブジェクト指向言語について、メリットとデメリットをまとめてきました。

対になるように書いてきたつもりではありますが、この辺りで1回きちんとまとめましょう。


難易度が低いのは手続き型

コードの読みやすさや難易度の低さから、学習コストが低いのが手続き型言語のメリットです。

新規開発でのコードの書きやすさでは、手続き型言語に分があります。ちょっとした1回限りのスクリプトを書くのにも便利でしょう。

今までプログラムを触ったことがない初心者の方が、コードを書くのに慣れるのも手続き型の方が向いているかもしれません。


再利用性と保守性ではオブジェクト指向型

コードの再利用性ではオブジェクト指向型が有利です。

各々の処理に特化した手続き型のモジュールは使い回すのが難しいですが、抽象化した役割であるオブジェクトであれば使い回せます。

オブジェクトは組み合わせて使用することもできるため、更に再利用性は高いといえるでしょう。

更に保守性でもオブジェクト指向に軍配が上がります。

カプセル化により他のオブジェクトの修正が他のオブジェクトに及ぼす影響範囲が明確になり、調査やテストがしやすくなるためです。


オブジェクト指向については、以下の記事でも詳しくご紹介しています。宜しければ、ぜひ併せてご参照ください。

オブジェクト指向とは?オブジェクト指向の基本を徹底解説!メリットやカプセル化の概念は?おすすめオブジェクト指向言語も紹介


Pythonのプログラミングパラダイム



Pythonには手続き型(Procedural)・オブジェクト指向型(Object-oriented)の他に2種類の型が存在します。

  • 命令型(Imperative)プログラミング言語
  • 関数型(Functional)プログラミング言語

本項で順番に説明しましょう。


命令型(Imperative)プログラミング言語

命令型プログラミングは手続き型プログラミングと同じ意味で使われることが多いパラダイムになります。

というのも手続き型プログラミングは命令型プログラミングの真部分集合にあたるパラダイムだからです。

本記事でも厳密に区別はしません。


関数型(Functional)プログラミング言語

代表的な関数型プログラミング言語はHaskell・Elmなどです。

関数型プログラミングでは全ての処理を数学的な関数で表現しようとします。データと振る舞いは厳密に分けるものです。

例えば料理レシピの話であれば、材料・道具・作り方を厳密に区別されている状態でしょう。

野菜を切る振る舞いであれば入力データは材料の丸ごと野菜、出力データは一口大に切られた野菜です。

入力データが決まれば結果が必ず一意に決まります。


状況に合わせて最適に選択する



プログラミングパラダイムは用途に合わせて適切なものを選択するのが大事です。

複数メンバーが関わるような大規模な開発や、複雑な処理をするプログラムを実装するならオブジェクト指向型が良いでしょう。

一方で一時的に必要な処理やデータ分析のための簡単なスクリプトであれば、わざわざ複雑なクラス設計をする必要はないと思われます。

短時間で短い処理を書くのに手続き型プログラミングは有効です。

Pythonはこれらのパラダイムの中から、好きなものを状況に合わせて選択・実装することができます。


おわりに



本記事では手続き型言語とオブジェクト指向言語の違いについて、例えを交えながら解説を行いました。

今後オブジェクト指向よりも優れた、全く考え方の異なる言語が出てきてもおかしくはないでしょう。

今までのプログラミングパラダイムを理解するのも良いことです。

しかし肝心なのは新しいパラダイムを的確に素早く理解できる頭の柔らかさではないでしょうか。

まずはブログ記事や専門書を読み、自分の中で消化して己の言葉で説明できる状態を目指しましょう。

手始めに冒頭に記載したいくつかのプログラミングパラダイムについて、自分の言葉で説明できるか試してみて下さい。


SHIFTフリーランスは、SHIFTグループがプライムとして参画している独自案件をフリーランスエンジニア向けに紹介する唯一のプラットフォームサービスです。

エージェントによるサポートもありますので、ご利用を検討してみてはいかがでしょうか。