031.1 レッスン 1
Certificate: |
Web開発の要点 |
---|---|
Version: |
1.0 |
Topic: |
031 ソフトウェア開発とWebテクノロジー |
Objective: |
031.1 ソフトウェア開発の基本 |
Lesson: |
1 of 1 |
はじめに
最初のコンピュータは、ケーブルをソケットに差し込むという大変な作業でプログラムされていました。その後、コンピュータ科学者たちは、コンピュータに何をすべきかを簡単に伝える方法を求めて、終わりのない研究を始めました。この章では、プログラミングのツールを紹介します。プログラマが達成したいタスクを表現するテキスト命令(プログラミング言語)の主要な方法と、プログラムをコンピュータが実行できる 機械語 と呼ばれる形式に変更するツールについて説明します。
Note
|
本文中では、 プログラム と アプリケーション という言葉は同じ意味で使われています。 |
ソースコード
プログラマは通常、アプリケーションを開発する際に、必要なタスクを ソースコード と呼ばれるテキスト形式の記述で表現します。ソースコードは、コンピュータができることを、人間が理解できる高度な抽象度で表現した、慎重に定義された プログラミング言語 で書かれています。プログラマやノンプログラマが自分の考えを視覚的に表現するためのツールも開発されていますが、ソースコードを書くことがプログラミングの主流となっています。
自然言語に名詞、動詞、構文があり、考えを構造的に表現するのと同じように、プログラミング言語の単語や句読点は、機械上で実行される操作を記号的に表現したものです。
この意味では、ソースコードは、作者が自然言語の確立されたルールを用いて読者とコミュニケーションをとる他のテキストとあまり変わりません。ソースコードの場合、 “読む人” は機械ですから、テキストに曖昧さや矛盾が含まれることはありません(たとえ微妙なものであっても)。
また、複雑なアプリケーションを開発する際には、あるテーマを深く掘り下げたテキストと同様に、ソースコードもしっかりと構造化され、論理的に整理されている必要があります。非常にシンプルなプログラムや教訓的な例は、1つのテキストファイルの数行に収めることができ、そのファイルにはプログラムのソースコードがすべて含まれています。より複雑なプログラムは、それぞれが何千行の数千ファイルに細分化されます。
高機能なアプリケーションのソースコードは、通常、特定の目的に関連した異なるフォルダに整理する必要があります。例えば、チャットプログラムは、ネットワーク上でのメッセージの送受信を処理するコードファイルを格納するフォルダと、インターフェイスを構築してユーザーのアクションに対応するファイルを格納するフォルダの2つに整理することができます。実際、アプリケーション内の非常に特定のタスクに特化したソースコードファイルが、多くのフォルダやサブフォルダに入っているのが一般的です。
また、ソースコードは、すべてが単一の言語で書かれたファイルに隔離されているとは限りません。例えば、Webアプリケーションでは、HTML文書にJavaScriptのコードを埋め込み、文書に追加機能を持たせることができます。
コードエディタとIDE
ソースコードの書き方には様々な方法がありますが、それだけでは圧迫感があります。そのため、多くの開発者は、プログラムの記述やテストを支援するツールを活用しています。
ソースコードファイルは、単なるテキストファイルです。そのため、どんなに簡単なテキストエディタでも編集することができます。ソースコードとプレーンテキストの区別を容易にするために、各言語では、C言語には .c
、Pythonには .py
、JavaScriptには .js
など、わかりやすいファイル名の拡張子が採用されています。一般的なエディタは、人気のある言語のソースコードを十分に理解しているので、イタリック体やカラー、インデントなどを追加して、コードを理解しやすくしています。
すべての開発者が、汎用のエディタでソースコードを編集することを選ぶわけではありません。 統合開発環境 (IDE)は、テキストエディタに加えて、プログラマが構文エラーや明らかな不整合を避けるためのツールを提供します。これらのエディタは、特に経験の浅いプログラマにお勧めですが、経験豊富なプログラマも使用しています。
Visual Studio、Eclipse、Xcodeなどの一般的なIDEは、プログラマが入力した内容をインテリジェントに監視し、使用すべき単語を頻繁に提案したり(オートコンプリート)、コードをリアルタイムに検証したりします。また、ソースコードが変更されたときに問題を特定するための自動デバッグや自動テストも可能です。
経験豊富なプログラマの中には、柔軟性が高く、追加のパッケージをインストールする必要がないVimなどのシンプルなエディタを選ぶ人もいます。このようなプログラマは、外部のスタンドアローンツールを使用して、IDEを使用する際に組み込まれている機能を追加します。
コードのメンテナンス
IDEであろうと、スタンドアロンのツールであろうと、ある種の version control system (VCS)を採用することは重要です。ソースコードは、予期せぬ欠陥を修正したり、機能拡張を取り入れたりする必要があるため、常に進化しています。この進化の必然的な結果として、修正や機能強化が、大規模なコードベースのアプリケーションの他の部分と干渉することがあります。Git、Subversion、Mercurialなどのバージョン管理ツールは、コードに加えられたすべての変更と、その変更を行った人を記録するので、失敗した修正を追跡し、最終的には回復することができます。
さらに、バージョン管理ツールを使えば、チーム内の各開発者は、他のプログラマの作業を妨げることなく、ソースコードファイルのコピーを使って作業することができます。新しいバージョンのソースコードの準備が整い、テストが行われると、1つのコピーに加えられた修正や改良を他のチームメンバーが取り入れることができます。
現在最も普及しているバージョン管理システムであるGitは、リポジトリの多くの独立したコピーをさまざまな人が維持し、その変更を望むままに共有することができます。しかし、分散型のバージョン管理システムであれ、集中型のバージョン管理システムであれ、ほとんどのチームは、ソースコードとリソースが信頼できる1つのリポジトリを管理しています。いくつかのオンラインサービスは、ソースコードのリポジトリのストレージを提供しています。これらのサービスの中で最も人気があるのはGitHubとGitLabですが、GNUプロジェクトのSavannahも注目に値します。
プログラミング言語
様々なプログラミング言語が存在しています。10年ごとに新しい言語が発明されています。それぞれのプログラミング言語には独自のルールがあり、特定の目的のために推奨されています。構文やキーワードなどの表面的な違いはありますが、実際に言語を区別しているのは、それぞれの言語が表現している深い概念的なアプローチであり、 パラダイム と呼ばれています。
パラダイム
パラダイムとは、プログラミング言語の基礎となる前提条件を定義するもので、特にソースコードをどのように構成すべきかということを意味します。
開発者は、言語パラダイムから出発して、機械が実行するタスクを策定します。そして、そのタスクは、言語が提供する単語や構文を使って記号的に表現されます。
プログラミング言語は、映画の脚本のように、ソースコードに示された命令が順番に実行される場合、 手続き型と呼ばれる方式 です。ソースコードが関数やサブルーチンに分割されている場合は、メインルーチンが関数を順番に呼び出すようになっています。
以下のコードは、手続き型言語の例です。C言語で書かれており、地理的な図形の辺、面積、体積を表す変数を定義しています。変数 side
の値は、プログラムの実行時に呼び出される関数である main()
で代入されます。変数 area
と volume
は、main関数の前にある square()
と cube()
のサブルーチンで計算されます。
#include <stdio.h>
float side;
float area;
float volume;
void square(){ area = side * side; }
void cube(){ volume = area * side; }
int main(){
side = 2;
square();
cube();
printf("Volume: %f\n", volume);
return 0;
}
main()
で定義されたアクションの順序は、 side
、 area
、 volume
変数の値によって特徴付けられるプログラムの状態の連続性を決定します。この例では、 printf
文で volume
の値を表示したところで終了します。
一方、 オブジェクト指向プログラミング (以降はOOPと記述)のパラダイムは、プログラムの状態を独立したサブステートに分離することを主な特徴としています。これらのサブステートとそれに関連する操作が オブジェクト であり、プログラムの中で多かれ少なかれ独立した存在であり、特定の目的を持っていることからそう呼ばれています。
パラダイムが異なるからといって、プログラムが実行できるタスクの種類が制限されるわけではありません。前述の例のコードは、C++言語を使ってOOPパラダイムに基づいて書き換えることができます。
#include <iostream>
class Cube {
float side;
public:
Cube(float s){ side = s; }
float volume() { return side * side * side; }
};
int main(){
float side = 2;
Cube cube(side);
std::cout << "Volume: " << cube.volume() << std::endl;
return 0;
}
main()
という関数はまだ存在しています。しかし、オブジェクトの定義を導入するために、 class
という新しい単語が出てきました。定義されたクラスは Cube
という名前で、それ自身の変数とサブルーチンを含んでいます。OOPでは、変数は 属性 とも呼ばれ、サブルーチンは メソッド と呼ばれます。
この例に出てくるC++のコードをすべて説明することは、この章の範囲を超えています。ここで重要なのは、 Cube
には side
属性と2つのメソッドがあるということです。 volume()
メソッドは立方体の体積を計算します。
同じクラスから複数の独立したオブジェクトを作成することが可能で、クラスは他のクラスで構成することができます。
同じ機能でも違うように書くことができることや、この章の例は単純化しすぎていることに留意してください。CやC++にはもっと高度な機能があり、はるかに複雑で実用的な構造が可能です。
ほとんどのプログラミング言語は、1つのパラダイムを厳格に押し付けるのではなく、プログラマが1つのパラダイムの様々な側面を選択できるようになっています。たとえば、JavaScriptは、さまざまなパラダイムの側面を取り入れています。プログラマは、プログラム全体を、互いに共通の状態を持たない関数に分解することができます。
function cube(side){
return side*side*side;
}
console.log("Volume: " + cube(2));
この例はプロシージャ型プログラミングに似ていますが、関数は実行に必要なすべての情報のコピーを受け取り、関数のスコープ外で起こる変更にかかわらず、同じパラメータに対して常に同じ結果を生成することに注意してください。 関数型 と呼ばれるこのパラダイムは、数学的な形式主義の影響を強く受けており、すべての操作が自己完結しています。
もう一つのパラダイムは、システムの状態を記述する 宣言型 言語を対象としています。宣言型言語は、指定された状態をどのように実現するかを考えることができます。データベースへの問い合わせのための普遍的な言語であるSQLは、宣言型言語と呼ばれることもありますが、実際には、プログラミングの中でも独自の地位を占めています。
どんな状況でも採用できる普遍的なパラダイムはありません。また、プログラムが使用されるプラットフォームや実行環境でサポートされている言語によって、言語の選択が制限されることもあります。
例えば、ブラウザで利用されるWebアプリケーションは、ブラウザが普遍的にサポートする言語であるJavaScriptで記述する必要があります。(JavaScriptを作成するためのコンバータを提供している言語であれば、他の言語でも使用可能です。)つまり、Webブラウザ(Webアプリケーションの クライアントサイド または フロントエンド と呼ばれることもあります)では、開発者はJavaScriptで許可されているパラダイムを使用する必要があります。ブラウザからのリクエストを処理するアプリケーションのサーバサイドまたはバックエンドは、通常、別の言語でプログラムされますが、この目的のためにはPHPが最も一般的です。
パラダイムを問わず、どの言語にもコードに組み込むことのできる関数の ライブラリ があらかじめ用意されています。例示したコードのような数学的な関数は、ゼロから実装する必要はありません。なぜなら、その言語にはすでにその関数が用意されているからです。例えば、JavaScriptでは、最も一般的な数学演算を行うための Math
オブジェクトが用意されています。
さらに専門的な機能は、通常、言語ベンダーやサードパーティの開発者が提供しています。これらの追加リソースライブラリは、ソースコードの形で、つまり、それらが使用されるファイルに組み込まれる追加ファイルの形で提供されます。JavaScriptでは、 import from
を用いて埋め込みを行います。
import { OrbitControls } from 'modules/OrbitControls.js';
埋め込みリソースがソースコードファイルでもあるこのタイプのインポートは、いわゆる 解釈言語 で最もよく使われます。 コンパイル言語 では、とりわけ、コンパイル済みの機能を機械語に組み込むこと、つまり、 コンパイルされた ライブラリを使用することができます。次のセクションでは、これらの言語の違いについて説明します。
コンパイラとインタプリタ
ご存知のように、ソースコードはプログラムを記号的に表現したもので、実行するためには機械語に翻訳する必要があります。
大まかに言えば、翻訳には、将来の実行に備えてあらかじめソースコードを変換しておく方法と、実行時にコードを変換する方法があります。前者の形式の言語を コンパイル言語 、後者の形式の言語を インタプリタ言語 と呼びます。インタプリタ型言語の中には、プログラムをより早く開始できるように、コンパイルをオプションとして提供しているものもあります。
コンパイル言語では、プログラムのソースコードと、コンピュータが実行するプログラム自体が明確に区別されています。一度コンパイルされたプログラムは、通常、そのプログラムがコンパイルされたOSやプラットフォーム上でのみ動作します。
インタプリタ型言語では、ソースコードそのものがプログラムとして扱われ、機械語に変換する過程がプログラマには透過的に行われます。インタプリタ型言語では、ソースコードを スクリプト と呼ぶのが一般的です。インタプリタは、スクリプトを実行中のシステムの機械語に翻訳します。
コンパイルとコンパイラ
コンパイル型言語の代表格といえば、C言語です。C言語の最大の強みは、柔軟性と性能の高さです。高性能なスーパーコンピュータも、家電製品に搭載されているマイクロコントローラも、C言語でプログラミングすることができます。また、C++やC#(シーシャープ)なども人気のあるコンパイル言語の一例です。これらの言語は、その名が示すように、C言語を参考にしつつ、オブジェクト指向のパラダイムをサポートする機能を備えています。
CやC++で書かれた同じプログラムを、異なるプラットフォーム用にコンパイルしても、ソースコードにはほとんど手を加える必要がありません。プログラムのターゲットとなるプラットフォームを定義するのはコンパイラです。コンパイラには、プラットフォームに特化したものと、GCC( GNU Compiler Collection の略)のようなクロスプラットフォームのものがあり、それぞれのアーキテクチャに対応したバイナリプログラムを作成することができます。
Note
|
コンパイルプロセスを自動化するツールもあります。コンパイラを直接起動するのではなく、プログラマがファイルを作成して、自動的に実行されるさまざまなコンパイルステップを示します。この目的で使われる伝統的なツールは |
コンパイルの過程で、機械語のバイナリプログラムが生成されるとは限りません。一般的に バイトコード と呼ばれる形式でプログラムを生成するコンパイル言語もあります。スクリプトと同様に、バイトコードはプラットフォーム固有の言語ではないので、機械語に翻訳するインタプリタプログラムが必要になります。この場合、インタプリタプログラムは単に ランタイム と呼ばれます。
Java言語はこのアプローチを採用しており、Javaで書かれたコンパイル済みのプログラムは異なるOS上で使用することができます。なお、名前は似ていますが、JavaはJavaScriptとは無関係です。
バイトコードはソースコードよりも機械語に近いため、実行速度が比較的速くなる傾向があります。ただし、バイトコードの実行時には変換処理が残っているため、機械語にコンパイルした同等のプログラムと同じ性能を得ることは難しいです。
インタープリテーションとインタプリタ
JavaScript、Python、PHPなどのインタプリタ型言語では、プログラムを事前にコンパイルする必要がないため、開発や修正が容易になります。スクリプトは、コンパイルする代わりに、インタプリタと呼ばれる別のプログラムによって実行されます。通常、ある言語のインタプリタには、その言語自体の名前が付けられています。例えば、Pythonスクリプトのインタプリタは、 python
というプログラムです。JavaScriptのインタプリタは、多くの場合、Webブラウザですが、スクリプトはブラウザの外にある node
というプログラムによって実行することもできます。実行されるたびにバイナリ命令に変換されるため、インタプリタ言語のプログラムはコンパイル言語に相当するものよりも遅くなる傾向があります。
同じアプリケーションであっても、異なる言語で書かれたコンポーネントが存在することがあります。必要に応じて、これらのコンポーネントは、相互に理解可能な (API)Application Programming Interface を介して通信することができます。
例えば、Python言語は、非常に高度なデータマイニングやデータ集計機能を持っています。開発者は、このような処理を行う部分をPythonで記述し、より重い数値処理をC++のような別の言語で行うことができます。2つのコンポーネント間で直接通信できるAPIが存在しない場合でも、この戦略を採用することができます。Pythonで書かれたコードは、例えばC++で書かれたプログラムが使用できるような適切な形式のファイルを生成することができます。
どんな言語でもほとんどのプログラムを書くことができますが、開発者はアプリケーションの目的に最も合致した言語を採用するべきです。そうすることで、すでにテストされ、文書化されたコンポーネントを再利用することができます。
演習
-
ソースコードの編集にはどのようなプログラムが使えますか?
-
異なる開発者の作業を同じコードベースに統合するためにどのようなツールがありますか?
発展演習
-
例えば、ブラウザ上で遊べる3Dゲームを書きたいとします。WebアプリやゲームはJavaScriptでプログラムされています。すべてのグラフィック機能を0から記述することも可能ですが、既製のライブラリを使用したほうが生産性が高くなります。JavaScriptの3Dアニメーション機能を提供するサードパーティのライブラリは何ですか?
-
Webアプリケーションのサーバサイドでは、PHP以外にどのような言語が使用できますか?
まとめ
このレッスンでは、ソフトウェア開発の最も基本的なコンセプトについて説明しました。開発者は、重要なプログラミング言語と、それぞれの適切な使用シナリオについて知っておく必要があります。このレッスンでは、以下の概念と手順を説明しました。
-
ソースコードとは何か。
-
ソースコードエディタと関連ツール。
-
手続き型、オブジェクト指向、関数型、および宣言型プログラミングの例。
-
コンパイル型言語およびインタープリタ型言語の特性。
演習の回答
-
ソースコードの編集にはどのようなプログラムが使えますか?
原則として、プレーンテキストを編集できるプログラムであれば何でもOKです。
-
異なる開発者の作業を同じコードベースに統合するためにどのようなツールがありますか?
Gitなどのソースまたはバージョン管理システム。
発展演習の回答
-
例えば、ブラウザ上で遊べる3Dゲームを書きたいとします。WebアプリやゲームはJavaScriptでプログラムされています。すべてのグラフィック機能をスクラッチで記述することも可能ですが、既製のライブラリを使用したほうが生産性が高くなります。JavaScriptの3Dアニメーション機能を提供するサードパーティのライブラリは何ですか?
JavaScript用の3Dグラフィックスライブラリには、three.jsやbabylon.jsなど多くの選択肢があります。
-
Webアプリケーションのサーバサイドでは、PHP以外にどのような言語が使用できますか?
サーバホスト上で使用されるHTTPサーバアプリケーションがサポートするあらゆる言語。例としては、Python、Ruby、Perl、JavaScriptなどがあります。