オブジェクト指向とは何か?
一言で言えば、課題の扱いを楽にする ためのテクニックです。
それではちゃんとした説明を試みてみます。
あえてオブジェクト指向プログラミング的な説明は省いて純粋に"オブジェクト指向"について語ってます!
オブジェクト指向とは?
オブジェクト指向とは「関心の分離のためのパラダイム」の1つです。
さっそく謎めいた説明をしてみましたがちゃんと説明します
もう少し平易な言葉で言うと。
「そのまま扱うには複雑すぎる問題を、
オブジェクトという切り口で、
簡潔に表現することで理解する」
ということです。
これが「オブジェクト指向」です。
エンジニア(デザイナも?)の仕事というのはただ1つで「課題の解決」です。
課題が何なのか?を的確にとらえその解決策を考えて解決するというのがエンジニアの仕事です。
大抵の場合解決しなければいけない「課題」というのはとてもとても複雑なものです。
「ECサイトを立ち上げたい」
↓
- Amazon? モール型? 自社独自?
- どのサービスを使う?
- サーバはどこ? 保守はだれがやる? 24x365でやる?
- 電話番号は新しくとる?
- 個人情報はどうやって守る?
- デザインは? 写真は? 受注処理は誰がやる? 発注は? メールは?
- メールはテキスト? HTML? 写真はJPEG? CDN使う? アクセス数は?
- ボタンの色は?形は?インタラクションは?
...
このようにいくらでも考えないといけないことは出てきます。どれだけ頭の良いエンジニアでも「課題」をそっくりそのまま理解するのはとても苦労します。無理です。なので、その複雑な「課題」は何かしらの方法で小さな課題に切り分けて1つ1つ対応していく必要があるのです。
「小さな課題に分けて」とは言ったもののどうやって小さな課題に切り分けるか? ということを考えた場合に「オブジェクト」という単位に切り分けていくことで扱いやすくしようというのが「オブジェクト指向」なのです。
もちろんオブジェクト指向とは別のパラダイム、つまり、別の考え方もあります。"データ指向" というのは課題を "データ" によって切り分けていきます。DFDなどによって表現されます。"手続き型指向" というのは課題を "処理の流れ" によって切り分けていきます。フローチャートによって表現されます。これは優劣ではなく対象とする課題によって得意不得意が変わってくるのです。
ピザを切り分ける時に放射状に切るか縦横に切るかという選択肢があるのと一緒です。
この「オブジェクト指向」という「オブジェクトを単位とした物事の考え方」をプログラミングに使うのが「OOP=オブジェクト指向プログラミング」と言われるもので、これを分析や設計に使うのが「OOAD=オブジェクト指向による分析設計」です。UIデザインに使えば「OOUI=オブジェクト指向UI」です。
Tips. 小さな単位に分解することの凄さ
いままで書いた通りで基本的にやりたいことは「複雑な課題を扱いやすい大きさまで切り分ける」ことです。
小さな単位に切り分けると何がいいのでしょう? そこで実験です。この9個を覚えてみましょう。結構大変です。
ぶどう、みかん、牛乳、バター、じゃがいも、りんご、たまご、だいこん、にんじん
これを 3 x 3 の組み合わせにすると、あら不思議、簡単に9個覚えられたりします。
乳製品 --- 牛乳、 たまご、 バター
果物 --- ぶどう、 みかん、 りんご
野菜 --- じゃがいも、 にんじん、 だいこん
実際にやってみると本当に簡単に覚えられます。
「関心の分離」「オブジェクト指向」でやっていることはこういうことで、素のままでは複雑すぎたり多すぎたりして扱いづらい対象を理解しやすいところまで咀嚼する活動です。
さてオブジェクトとは?
前置きがが長くなりましたがオブジェクトとは何でしょう。
良く言う例では、車や、人や、犬、です。
もう少しプログラミング的な例で言えば「XXX Classのインスタンス」とかもちろんそれもオブジェクトです。
int a
や String b
の a
や b
もオブジェクトです。
ではいったいオブジェクトとは何なのでしょうか?
オブジェクトの簡単な定義は以下です。これだけです。世の中にはややこしいことを言う人がたくさんいますが定義はこれだけで十分です。
オブジェクトは他のオブジェクトと区別可能であるもの
例えば、だいこん と にんじん は区別可能でしょうか? 可能ですね、なので だいこん も にんじん もオブジェクトです。
let a
と let b
のa
とb
は区別可能でしょうか?可能ですね。 a
と b
ですから。
でも
let
とlet
は区別つきませんよね? なのでlet
はオブジェクトじゃないのです
では、次のコードの1行目と3行目のa
はどうでしょう。これも区別可能ですね。スコープが違いますね。細かくいうと配置されているアドレスが違います(&a != &b
)。区別可能です。1: int a; 2: if(true){ 3: int a; 4: }
現実世界に双子がいてまったく同じ姿かたちであろうとその2人は物理的な座標が必ず違うので区別可能です。
大量生産された自動車も必ず何かしらの方法で区別可能です。
画面上にボタンが2つあってもそのボタンは場所がちがっていたり文字が違っていたり前後が違っていたり必ず区別可能です。
名前と年齢も区別可能です。人と車も区別可能です。歩くと走るも区別可能です。
つまりはどんなこじつけでもしてしまえば世の中のモノほとんどすべてがオブジェクトということが可能です。
オブジェクトは属性と操作を持つ等の説明もあります。クラスとインスタンスの話や写像の話やややこしい説明はたくさんあります。それらはもちろん間違ってはいませんが、それは付随的なものであって、大事なのは「識別可能である」というただ1点です。
このオブジェクトに対する柔軟な捉え方が可能というのがオブジェクト指向の最大の武器でもあり、同時に、慣れない人にとっての使いづらさでもあります。
オブジェクトじゃないものの代表例に「車」などがあります。
具体的な車種名ではなく抽象的な意味での「車」ではすべての車がただの「車」になってしまうので「車」と「車」は区別がつかないです。区別がつかない以上これはオブジェクトではないです。
ただこれも詭弁で、「人」と「車」は区別がつくので区別がつくなら「車」はオブジェクトだと言うこともできます。
つまり何がオブジェクトか?というのはその時々の文脈によって変わってしまうので正解は無いということです。
オブジェクト指向のメリット
では、なんでオブジェクト指向なんてものを使うのでしょうか?
答えは簡単で、課題の扱いが楽になるから、です。
もう少し言うと、オブジェクト指向は課題の扱いが楽になるように様々なテクニックが組み込まれている手法だから、です。
簡単な例で言うと例えば「ECサイト」。一言でいえば「ECサイト」ですが中身は、画面、認証、ユーザ管理、決済、ロジスティクスとの連携、ユーザサポート……多種多様な機能の組み合わせです。これを「ECサイトを作ろう!」だけでは誰も何も理解できませんし相手が大きすぎるので一筋縄ではいきません。なので「認証機能」とかを切り出します。さらに「ID」「パスワード」などを切り出します。「ECサイト」を作るのは大変ですが「ID」を制御するだけならまだできます。「IDオブジェクトは、文字列でIDを保持して、文字長は10文字までで、文字種類のバリデーションができて…」と言った感じです。これくらいなら新人研修の一環でも作れそうですよね。
この分割の仕方も名詞抽出法など様々なテクニックがありますが略
さらにオブジェクト指向ならではなのテクニックとして代表的なものにはオブジェクト指向の3要素とよく言われている「カプセル化」「継承」「ポリモーフィズム」などもあります。
個人的にはこれよりも、オブジェクト指向の基本5原則をおススメしたいですが…… 話がそれるので止めておきます
「カプセル化」「継承」「ポリモーフィズム」の説明は思い切って省略してしまいますが、1つだけ例を。
例えば「継承」ってよく聞くけど何のためにあるのでしょうか?
そうです何度も行ってますが、課題の扱いが楽になるから、です。
少し上流のビジネス目線の例を考えた場合、
- 店員は、レジが打てる、接客ができる
- 店長は、仕入れができる
- 店長は、店員である(店長 is a 店員 = 店長は店員を継承している)
"店長"は"店員"でもあると言ってます。つまり"店長"でもちゃんとレジが打てるし接客もできるということが表現されています。
これを「継承」という概念なしに理解しようとした場合には以下のようになります。
- 店員は、レジが打てる、接客ができる
- 店長は、レジが打てる、接客ができる、仕入れができる
これだと同じ内容が2つ書いてあり、理解しなければいけない量が2倍近くになっています。
こんな簡単な例だと大丈夫ですが、これが複雑になっていくと簡単に人間の理解できるキャパをオーバーしてしまいます。
・・・
カプセル化、デザインパターンなどの各種テクニックもつまりはこういうことで、課題の扱いを楽にするためのノウハウなのです。
オブジェクト指向のデメリット
もちろんデメリットもあります。
ちゃんと知っておきましょう。
オブジェクト指向を使うまでもないような簡単な対象にオブジェクト指向を使うと、無駄に複雑になりすぎます。
オブジェクト指向は(複雑な)課題を扱うのを楽にするための手法なので最初から簡単ですぐに理解可能なものへ使おうとするとただ闇雲に複雑になってしまいます。
例えば「データ」だけを扱うような仕組みにオブジェクト指向を入れると煩雑になることが多いです。それはデータ思考=データ中心の考え方で考えた方が良いです。
他にも少し難しい例ですが「横断的な関心事」の表現が苦手です。「アスペクト指向」みたいな手法の方が得意とする分野です。
複雑だからと言ってなんでもかんでもオブジェクト指向が良いわけでもありません。
まとめ
オブジェクト指向界隈は、オブジェクト指向での分析、モデリング、オブジェクト指向プログラミング、GoF/GRASPのデザインパターン、さまざまなトピックがあり、とても複雑な広い分野になっています。一言に「オブジェクト指向」と言っても何を指しているかわかりません。
加えて、小手先の、枝葉の、トピックが多いのも事実です。
(小手先の枝葉のトピックも大事ですが本質を見えづらくしているのも確かです)
そういうのに振り回されてしまうとだんだんと本質から離れていってしまって、わけのわからない誤解や誤認識で「オブジェクト指向意味わからん」「オブジェクト指向役に立たない」なんて言い始めて、身動きがとれなくなってしまうことがあります。
ということで今回の投稿では改めて「オブジェクト指向」とは何か?について、かなり抽象的な、かつ、本質的な観点で語ってみました。
これを思い出してくれた上で、オブジェクト指向の参考書に書かれている例題や、オブジェクト指向の基本5原則、カプセル化・継承・ポリモーフィズムを見ることでもう少しオブジェクト指向と仲良くしてもらえるとよいなあと思います。