クラスと秩序と設計の話
こんにちは、松本です。
今日からしばらく設計の話をします。
プログラミング初心者の方に、
「クラスってなんで要るの?別に変数とか関数をたくさん並べればよくない?わざわざ別ファイルで新しい.swift作るの面倒」
と聞かれました。
はい、たしかにその通りで、クラスとして構造をまとめなくて変数をズラズラ並べれば動きます。
例えば、写真のファイル名と撮影場所の緯度、経度を表現したクラスを作ったとします。
クラスの例
class Picture {
let _fileName:String //画像のファイル名
let _latitude:Double //緯度
let _longitude:Double //経度
//イニシャライザ
init(fileName:String,latitude:Double,longitude:Double) {
_fileName = fileName
_latitude = latitude
_longitude = longitude
}
}
『init』と言うのはイニシャライザで、クラスを使う時に自動で呼ばれる特別なファンクションです(特別なので最初に"func"と書かなくていい)。
このPictureクラスを使って3枚の写真を表現すると、
let skyPic = Picture(fileName:"sky.jpg",latitude:35.14567,longitude:139.87951)
let foodPic = Picture(fileName:"food.jpg",latitude:36.85694,longitude:120.89612)
let mtPic = Picture(fileName:"mountain.jpg",latitude:34.456614,longitude:140.745621)
こんな感じになります。ファイル名とか経緯度は適当ですよ。
さて、これでskyPicの経緯度を扱いたければ、それぞれ『skyPic._latitude』と『skyPic._longitude』を書けばOKです。
mtPicのファイル名は『mtPic._fileName』に入っています。
つまり、『なんとか"の"なんとか』という感じで扱えます。
クラスを使わない例
これをクラスなしで書くとこうなります。
let skyPicFileName:String = "sky.jpg"
let skyPicLatitude:Double = 35.14567
let skyPicLongitude:Double = 139.87951
let foodPicFileName:String = "food.jpg"
let foodPlcLatitude:Double = 36.85694
let foobPicLongitude:Double = 120.89612
let mtPicFileNome:String = "mountain.jpg"
let mtPicLatituude:Double = 34.456614
let mtPicL0ngitude:Double = 140.745621
一瞬見ただけで「うっ…」となりませんか。
おまけに、よく見ると変数名に微妙な間違いがあります。でもエラーにはならないので気づきません。
『なんとか"の"なんとか』という形でアクセス出来ないので、上だと『mtPic._fileName』とアクセス出来たものが『mtPicFileName』という、長い変数名になってしまいます。
まだこの程度の長さならいいですが、『mtPic._fileName._createTime.since1970Second』くらい長くなると、『mtPicFileNameCreateTimeSince1970Second』なんて、変数名としてどうかと思うような長さになります。
実用上問題があります。
データを構造化すると理解しやすくなる
例えば、住所は構造化されています。
都道府県があって、市区町村があって、町があって番地があります。
クラスでのアクセスっぽく書くと『東京都.江戸川区.東葛西.5丁目.15番地』と書けます。これが、各々勝手な住所を設定できるとどの辺に住んでるのか想像もできなくなりますね。
クラスを使わない世界というのは、「日本の真ん中くらいの大きな川のほとりの赤い三角屋根の家の吉田」という住所が許されてしまうくらいカオスになります。
『クラス』は『プログラムに秩序とルールを作るために』に必要なのです。
動かそうと思えば動くけど、必要なもの
さっきの『クラスを使わない例』で書いたように変数をズラズラ並べて、それをきちんと頭で管理して使いこなせばプログラム自体は動きます。
昔のBASICやC言語にはクラスが無かったので(※1)、上記のように変数をズラズラ並べて書いたりしました。
そしてそれは、途方もないバグと混乱との戦いだったのです。
紙に印刷してデータをグループ化したり、大量のコメントを書いたり、長時間かけて構造を頭に叩き込み、奮闘し、そして散っていきました(散ったのかよ)。
昔のプログラミングというのは、とにかく果てしない複雑さとの戦いだったのです。
そして戦いに勝つために人類が発明したのがオブジェクト指向で、その実用品が『クラス』です。
使いこなせば助けになる
(大雑把に言えば)クラスは『変数とファンクション』を持ちます。
変数もまとめられるし、ファンクション(機能)もまとめられます。
変数や機能を一つのブロック(オブジェクト)として扱えるので、構造の理解と管理が非常にやりやすくなります。
巨大なアプリやシステムでも、細かい部分が全体に影響を与えないように作れます。
(最初は分からなくても、大きなものを作れば理解できます)。
最初は小さなアプリでも、開発を続けていけば徐々に大きくなっていきます。
最初はクラスなんか作らなくても動くけど、複雑さが増していくとどこかで破綻します。
だから、最初からクラスに出来る部品やデータの塊はクラスとしてきちんと定義しておくとよいのです。後で後悔せずに済みます。
こういうものがいっぱいあります
クラスに限らず、オプショナル型とか、引数のラベル(※2)なんかも、『プログラムに秩序とルールを作るために』あります。
プログラミング初心者が『なんでこんな機能があるの?回りくどくない?これ使わなくても動くよね?』と不思議に思うものはだいたい『秩序維持』のためにあります。
初心者は複雑で巨大なものを作ったことがないので、ピンと来ないのも仕方ありません。カオスがいかにプログラマーを苦しめてきたか知らないから…。
自分でクラスなんか作らなくてもプログラム自体は動きます。
ただし、プログラムが巨大になっていくと絶対に破綻します(※3)。
破綻する前にプログラム中に秩序を作っておかなくてはいけません。
その、秩序を作っていく作業を人は『設計』と呼びます。
そう、設計とは、システムに秩序を作ることなのです。秩序を作らないとプログラマーが死ぬからです!
ではまた次回。
注釈
※1
構造体とか配列とかはあったのでもう少しマシな書き方も出来ましたが、話を簡単にするために多少盛ります。
※2
Picture(fileName:"sky.jpg",latitude:35.14567,longitude:139.87951)
↑これのfileName:、latitude:、longitude:のこと。
※3
人智を超えた天才なら破綻せずに書けるかもしれませんが。例えば将来のAIが書くプログラムはおそらく人智を超えたスパゲッティコード(複雑に絡み合ったコード)でしょう。
わぁい、サポート、あかりサポートだい好きー。