LoginSignup
16
9

More than 1 year has passed since last update.

プログラムの命名は立派な設計行為

Last updated at Posted at 2022-11-05

はじめに

最近、技術書で「良いコード/悪いコードで学ぶ設計入門 ―保守しやすい 成長し続けるコードの書き方」という本に出会いました。

自分に足りていなかった設計の考え方についてかなり勉強になりました。
本当に良かったので内容を忘れないようにQiitaに書き残そうと思います。またこれを機にアウトプットの習慣化ができればいいなと思っています。

動くプログラムは割と誰にだって書けると思いますが、良い構造へ改善するためのアプローチを知っている人は世の中に少ないのではないかと思います。
その少数派、価値の高いレイヤーに参加できる入門書が本書だと思いました。

その中でもまずは「名前設計」について執筆していきたいと思います。

目次

  1. 意味不明な命名
  2. 命名は省略を避けよう
  3. 変数の使いわましを避けよう
  4. 名前設計を怠ったプログラムの末路
  5. 参考文献

意味不明な命名

UnintelligibleNaming.swift
// 何してるんだ・・・?
var d = 0
d = p1 + p2
d = d - ((d1 + d2) / 2)
if (d < 0) {
    d = 0
}

このコードだけ見たエンジニアは、このコードが何をしたいのか見当もつかないはずです。
このコードは何と「ゲームの相手に与えるダメージ計算ロジック」なんですって。
なぜこんなにも難解なコードになってしまったのか、原因は明確で「変数名の省略」です。

下記が対応表になります。

変数 意味
d ダメージ量
p1 プレイヤー本体の攻撃力
p2 プレイヤーの武器の攻撃力
d1 敵本体の防御力
d2 敵の防具の防御力

命名は省略を避けよう

つまり、全て日本語に置き換えると下記のようになります。

UnintelligibleNaming.swift
var ダメージ量 = 0
ダメージ量 = プレイヤー本体の攻撃力 + プレイヤーの武器の攻撃力
ダメージ量 = ダメージ量 - ((敵本体の防御力 + 敵の防御力) / 2)
if (ダメージ量 < 0) {
    ダメージ量 = 0
}

なので、省略せずに名前設計をすると下記のようなコードになります。

UnintelligibleNaming.swift
var damageAmount = 0
damageAmount = playerArmAmount + playerWeaponPower
damageAmount = damageAmount - ((enemyBodyDefence + enemyArmorDefence) / 2)
if damageAmount < 0 {
    damageAmount = 0
}

一番最初の命名が省略されたコードと比較すると可読性が上がったと思います。

UnintelligibleNaming.swift
var d = 0
d = p1 + p2
d = d - ((d1 + d2) / 2)
if (d < 0) {
    d = 0
}

変数の使いわましを避けよう

UnintelligibleNaming.swift
var damageAmount = 0
damageAmount = playerArmAmount + playerWeaponPower // ・・・ ①
damageAmount = damageAmount - ((enemyBodyDefence + enemyArmorDefence) / 2)
if damageAmount < 0 {
    damageAmount = 0
}

改善が見られたように思えるこのコードですが、まだ修正すべき点があります。
damageAmountに目的に沿わない再代入が行われている点です。

①の処理を和訳すると
「プレイヤー本体の攻撃力とプレイヤーの武器の攻撃力を足したものはダメージ量です」となります。ですが本来は
「プレイヤー本体の攻撃力とプレイヤーの武器の攻撃力を足したものはプレイヤーの攻撃力です」が正しいはずです。

コードで書いてみましょう。

UnintelligibleNaming.swift
let playerAttackPower = playerArmAmount + playerWeaponPower

こちらの方が目的に合った変数を用意できて、可読性が高いと思われます。

全体的に修正を加えると、下記のようになります。

UnintelligibleNaming.swift
let playerTotalAttackPower = playerArmAmount + playerWeaponPower
let enemyTotalDefence = enemyBodyDefence + enemyArmorDefence
var damageAmount = playerTotalAttackPower - (enemyTotalDefence / 2)
if damageAmount < 0 { damageAmount = 0 }

攻撃力と防御力とダメージ量の目的ごとの変数が用意され、各変数の関係性が分かりやすくなったと思います。

ご紹介させていただいた技術書では、この後に「メソッド化、クラス化をしていこう」という流れになります。
この記事は名前設計について執筆させていただきたいので趣旨がズレるため割愛させていただきます。

名前設計を怠ったプログラムの末路

本記事の考えは、「名前に注意を払い、名前とロジックを対応付ける」ことを前提としています。従って、名前に無頓着だと全てが瓦解します…。

名前設計を怠った場合に、高確率で闇コードが出来上がってしまいます。
開発者一人一人が名前設計について向き合わなければいけません。

参考文献

16
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
9