こんにちは!
株式会社OGIXのエンジニアH.Nです。
今日は、『美しいコード』について、自分なりに言語化してみたいと思います。
この記事は個人の考えを述べたものです
言語化が若干無理やりなところもありますが、ご容赦ください
最初に
『美しいコード』というと、非常に主観的で、人によって基準が違ったり、言語、流派によって変わったりするものかもしれません。
プログラミングの世界から離れて、一般的に、『美しい』とは何でしょうか。
- 美しい構図
- 美しい色使い
- 美しい造形
- 美しい文章
- 美しい数式
- 美しいロジック
世の中には、いろいろな『美しい』が存在していることが分かります。
美を追求するアートやデザインの世界はもちろん、純粋なロジックの世界である数学の世界においても、『美しい数式』という概念は存在しています。
そこで、今回は『美術的な美しさ』『文学的な美しさ』『数学的な美しさ』の3つの観点から、『美しいコード』を言語化してみたいと思います。
美術的な美しさ
美術の世界では、ただ「キレイだね!」というだけではなく、様々な手法によって美しく見せることが研究されています。
三分割法
画面を3✕3に分割し、交点となる位置に主役の被写体を置くことで、バランスよく見える、という手法です。
黄金比
約1:1.61の比率が『美しい』とされています。
名刺のサイズなどに応用されていますね。
トーン
彩度と明度を組み合わせて、トーンを定義することができます。
トーンによって、見る人に様々な印象を与えることができます。
これらから、『見た目のバランスの良さ、色の組み合わせ』が、美術的な美しさとしてプログラミングに応用できそうです。
インデント&改行のルール統一
// {}は右肩に乗せるスタイル
function warizan(a, b) {
if (b === 0) {
throw Error("0で割ってはならない");
}
return a / b;
}
// {}は改行するスタイル
function warizan2(a, b)
{
if (b === 0)
{
throw Error("0で割ってはならない");
}
return a / b;
}
インデントや改行のルールを統一することで、見た目が統一され、読みやすいコードになります。
if else の改行位置や、{}の改行スタイルなども、統一することで読みやすくなるでしょう。
深すぎるネストはNG
if (conditionA) {
if (conditionB) {
if (confitionC) {
if (conditionD) {
...
}
}
}
}
ネストが深すぎると、見た目にバランス悪く、エディタで処理を読むのも大変です。
もちろん、どうしても深くならざるを得ない時もありますが、早期リターンなどを使ってネストを浅くしたいところです。
見た目から処理の概要を推測できる
const myFunction = x => x * 2;
言語にもよりますが、例えばアロー関数であり中括弧{}が省略されているものは、内部で手続き的なことをしない、シンプルな関数だと想像することができます。
言語機能をうまく使って、見た目からどのような関数か伝えられるとよいと思います。
IDEのカラー設定
コードからは少し離れますが、IDEのカラー設定も大事なのではないでしょうか。IntelliJでコーディングしていたものをGitHubに上げると、コードの色付けが変わって、印象が変わるのは良くあることかと思います。
人によって好みあると思いますが、見やすい、長時間見て疲れない、ような色合いが良いかもしれません。
文学的な美しさ
次に文学の世界です。
文学の世界では、どのような文章が『美しい文章』といわれているのでしょうか。
川端康成の雪国
国境の長いトンネルを抜けると雪国であった。夜の底が白くなった。信号所に汽車が止まった。
極めてシンプルでありながら、読者に風景を想像させ、主人公やこれからはじまる旅についても連想させる、素晴らしい文章ですね!
松尾芭蕉の俳句
荒海や 佐渡に横とう 天の川
日本古来の和歌や俳句に使われている七五調。
日本語は5文字7文字を意識して並べていくとリズムが良くなるようです。
和歌や俳句は、短い文章でありながら読者に多くを想像させる、素晴らしい文章ですね。
このように、『簡潔でありながら読者に想像させる文章』が、文学的な美しさとしてプログラミングに応用できそうです。
命名ルールの統一
- 意味のある名前をつける
変数名や関数名には、その役割や内容が分かるような名前を付ける。 - 短すぎず長すぎず
名前は短すぎず、意味が分かる範囲で長すぎないようにする。例えば、iやxといった短すぎる名前は避け、indexやcoordinateなど具体的な名前を使う。 - 一貫性を保つ
プロジェクト全体で同じ命名規則を使用する。例えば、クラス名は常にパスカルケース、変数名はキャメルケースなど。 - 略語は慎重に選ぶ
略語を使用する場合は、一般的に理解されるものに限る。例えば、numはnumberの略として広く認知されているが、独自の略語は避ける。 - 関数名は動詞、変数名は名詞
関数名は通常、動詞で始める(例: calculateTotal、getUser)。変数名やオブジェクト名は名詞を使う(例: totalAmount、user)。
コードは文章であり、プログラマーは読者でもあります。
isXXXXやcanXXXXなどのように接頭辞や接尾辞を統一したりすることで、読者は変数名、関数名から中身の処理を連想できるようになります。
また、言葉として正しい言葉を使うことも、読者に意味を伝える上で大事でしょう。
適切なコメント
// 引数numberが素数かどうかを判定する
function isPrime(number) {
// 2未満の数は素数ではない
if (number < 2) return false;
// 2は素数である
if (number === 2) return true;
// 偶数は素数ではない
if (number % 2 === 0) return false;
// 奇数のみをチェックする
for (let i = 3; i <= Math.sqrt(number); i += 2) {
if (number % i === 0) return false;
}
return true;
}
コメントは大事ですが、だからといって何でもかんでもつければよいというものでもありません。
読者の気持ちを想像し、説明しておくべきこと、補足しておくべきこと、逆に処理を見れば分かるのでコメントは控えるべき場合、など判断して、適切な粒度でつけると良いと思われます。
数学的な美しさ
最後に数学の世界です。
数学にはどのような美しさがあるのでしょうか。
オイラーの公式
$$ e^{i\theta} = \cos\theta + i\sin\theta $$
有名なオイラーの公式です。
θにπを代入すると$$ e^{i\pi} + 1 = 0 $$となり、円周率、ネイピア数、虚数単位、1、0という、数学の世界の重要な数たちが、シンプルな式で結びついています。
シンプルかつ意外性のある結びつきが、数学的な美の要素といえそうです。
モーリーの定理
任意の三角形において、各内角の三等分線どうしが最初に出会う点は正三角形をなす。
マジで!って感じですよね!
証明はWikipediaをご覧ください。
角の三等分線をどうやって作図するかは置いておいて、
任意の三角形において成り立つという普遍性、三角形の中から正三角形が出てくるという図形的な美しさ、角の三等分線を引くという操作から正三角形が出てくるシンプルさと意外性、が感じられる定理だと思います。
これらのことから、『シンプルでロジックが美しく、対称性など法則のあるもの』が、数学的な美しさとしてプログラミングに応用できそうです。
ロジックの本質が見えるコード
quickSort [] = []
quickSort [x] = [x]
quickSort (x:xs) = quickSort left ++ [x] ++ quickSort right
where
left = filter (< x) xs
right = filter (>= x) xs
Haskellのクイックソートです。
厳密にはクイックソートとしてよろしくないとの声もありますが、コード例ですのでご容赦ください
クイックソートの本質である、番兵を選んで配列を分割し、再帰を行う流れが、コード上で明確に見ることができます。
シンプルでありながら、ロジックの本質を伝えてくれる、美しいコードだと思います。
関数型言語は、数式を素直にコードに落としやすいところが良いですね。
宣言的な記述
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const newArray = array
.filter(x => x % 2 === 0)
.map(x => x * x);
この例では、配列内の要素から偶数だけ取り出し、2乗しています。
本質的には、配列という集合から偶数だけ取り出して、2乗するファンクションを適用している操作です。
for文を回すのに比べて、配列に対してどのような操作をしているか分かりやすく、数学的な意味合い(配列という集合に対して写像を適用する)にも近しいので、こちらの記法の方が好まれることも多いでしょう。
依存関係やクラスの結合
クラスどうしの結合、依存関係は、数学的構造とはいえないかもしれませんが、正しく設計されたクラス図はある種の美しさがあると思います。
例えば、クリーンアーキテクチャに登場するあの同心円のような構造は、依存の流れが一方通行であり、構造的な美しさがあると思います。
まとめ
いかがだったでしょうか。
- 美術的な美しさ...見た目のバランスの良さ、色づかい
- 文学的な美しさ...リズムよく簡潔でありながら読者に想像させる文章
- 数学的な美しさ...シンプルで美しいロジック、対称性など法則のあるもの
これらをコードに取り入れることで、『美しいコード』になっていくと思います。
また、時代や国によって美の基準は変わっていくものです。
その時の開発環境やチームメンバーに合わせて、『美しさ』を言語化していくことが重要だと思います。
一緒に働く仲間を募集しています!
株式会社OGIXでは一緒に働いてくれる仲間を募集しています!
エンタメ制作集団としてゲームのみならず、未来を見据えたエンタメコンテンツの開発を行っています。
事業拡大に伴い、エンジニアさんを大募集しています。
興味のある方は下記リンクから弊社のことをぜひ知っていただき応募してもらえると嬉しいです。
▼会社について
https://www.wantedly.com/companies/company_6473754/about
▼代表インタビュー
https://www.wantedly.com/companies/company_6473754/post_articles/443064
▼東京オフィスの応募はこちら
https://www.wantedly.com/projects/1468324
▼新潟オフィスの応募はこちら
https://www.wantedly.com/projects/1468155