オブジェクト指向
オブジェクト指向(object-oriented)は、データとそれを操作する手続きを「オブジェクト」という単位にまとめ、オブジェクト同士のメッセージのやり取りとしてシステムを組み立てるソフトウェア設計・プログラミングの考え方である。起源は1960年代のシミュレーション研究にあり、現在ではJava、C++、Pythonなど主要なプログラミング言語の多くが採用している。業務システムだけでなく、工場の生産設備を制御するプログラムにも取り入れられつつある。
シミュレーション言語から始まった歴史
源流は、ノルウェー計算センターのオーレ=ヨハン・ダールとクリステン・ニガードが開発したSimula 67にある。船舶の交通や待ち行列といった現実の対象を計算機上でシミュレーションするため、対象ごとにデータと振る舞いを束ねる「クラス」の概念が導入された。この発想を発展させたのが、米ゼロックス社パロアルト研究所(PARC)のアラン・ケイらである。ケイは1970年代初頭に「オブジェクト指向」という言葉を使い始め、1980年に公開されたSmalltalk-80では、数値を含むあらゆる要素をオブジェクトとして扱う徹底した設計を示した。産業界に広く普及するきっかけになったのは、ビャーネ・ストロヴストルップがC言語を拡張して1983年に名付けたC++と、1995年にサン・マイクロシステムズが発表したJavaである。
手続き型プログラミングとの違い
FORTRANやC言語に代表される手続き型では、処理の流れを関数の順序で記述し、データは関数の外に置かれる。小規模なら見通しはよい。しかし数万行を超えると、どの関数がどの変数を書き換えているのかを追いにくくなる。オブジェクト指向はこの問題に対して、データを持ち主のオブジェクトの中に閉じ込め、外部からは決められた窓口だけで操作させるという方針をとった。その結果、変更の影響範囲が限定され、大規模なソフトウェアを保守しやすくなる。
基本となる4つの概念
教科書的には次の4つが柱とされる。ただし、抽象化を除いた3本柱で説明する論者もおり、定義は完全には統一されていない。
- カプセル化:内部データを隠し、公開したメソッドを通してのみ操作させる
- 継承:既存クラスの性質を引き継いで新しいクラスを定義する
- ポリモーフィズム(多態性):同じ呼び出しに対して、オブジェクトの種類ごとに異なる処理を行わせる
- 抽象化:対象の本質的な特徴だけを取り出してモデル化する
クラスとインスタンス
クラスはオブジェクトの設計図にあたり、そこから実体として生成されたものをインスタンスと呼ぶ。たとえば「搬送コンベヤ」クラスに速度や稼働状態といった属性と、起動・停止のメソッドを定義しておけば、ライン上の12台のコンベヤをそれぞれ別のインスタンスとして扱える。速度設定は台ごとに独立して保持されるため、1台の設定を変えても残り11台には影響しない。
主要言語における採用状況
オブジェクト指向への取り組み方は言語によって濃淡がある。代表的な言語を比べると以下のとおりである。
| 言語 | 登場年 | 標準化 | 特徴 |
|---|---|---|---|
| Smalltalk | 1980(Smalltalk-80) | ANSI INCITS 319-1998 | すべてがオブジェクトの純粋型 |
| C++ | 1983 | ISO/IEC 14882 | 多重継承に対応し、組込み分野でも多く使われる |
| Java | 1995 | Java言語仕様(Oracle) | 単一継承とインタフェースを組み合わせる |
| Python | 1991 | 国際規格なし(PEPで仕様管理) | 動的型付けで、手続き型と併用しやすい |
| C# | 2000 | ECMA-334、ISO/IEC 23270 | .NET環境の設備監視アプリでの利用例が多い |
生産設備の制御プログラムへの展開
製造業で近年注目されているのが、PLCのプログラミング言語を定めた国際規格IEC 61131-3の第3版(2013年)である。この改訂でファンクションブロックにMETHOD、INTERFACE、EXTENDSといったキーワードが加わり、構造化テキスト(ST)でクラスに近い書き方ができるようになった。BeckhoffのTwinCAT 3やCODESYS V3は、この拡張にいち早く対応している。装置メーカーにとっては、シリンダやサーボ軸を部品化したライブラリを機種をまたいで使い回せるため、新しい装置の立ち上げ工数を減らしやすい。とはいえ、現場の保全担当者はラダー図に慣れていることが多く、継承の階層を深くしすぎると夜間のトラブル対応で原因箇所を追えなくなる。実務では、継承を2階層程度にとどめ、保全担当者が触る画面やI/O割付けは従来の形式のまま残す折衷案がよく採られる。
設計手法とUML
この考え方は、プログラムを書く前の分析・設計の段階にも広がった。1990年代にはブーチ法、OMT、OOSEなど複数の手法が乱立したが、それらを統合する形で1997年にOMG(Object Management Group)がUMLを標準化し、のちにISO/IEC 19501(2005年)として国際規格になった。クラス図、シーケンス図、状態マシン図などを使えば、プログラマ以外の関係者とも構造を共有できる。1994年には「Gang of Four」と呼ばれる4人の著者が23種類のデザインパターンを体系化し、再利用しやすい設計の定石として定着した。
批判と限界
万能の手法というわけではない。継承を多用すると、親クラスの変更が子クラス全体に波及する「脆い基底クラス問題」が起こりやすく、GoFの書籍自身も継承よりコンポジション(合成)を優先するよう説いている。リアルタイム性が厳しく求められる組込みシステムでは、仮想関数呼び出しや動的メモリ確保のオーバーヘッドを避けるため、MISRA C++などのコーディング規約で使い方を制限する例もある。2010年代以降は、RustやGoのようにクラス継承を持たず、インタフェースや合成で同じような設計を実現する言語も支持を集めている。
コメント(β版)