KISS原則(KISSの法則)は「Keep it simple, stupid」の頭文字を取った設計指針で、目的を満たす中で最も単純な作りを選び、必要以上の複雑さを持ち込まないことを求めます。読み方は「キスの原則」「キスの法則」です。
この記事では、KISSの意味と「stupid」が指すもの、ロッキードのケリー・ジョンソンにまつわる由来を一次資料で確かめた結果、コードで実践する書き換えをPythonで実行・計測した例、DRY・YAGNI・SOLIDとの優先順位、単純にしすぎて失敗する場面を順に扱います。
まとめ:KISS原則の要点
- 意味:「Keep it simple, stupid」。要件を満たしたうえで、構造が一読で追える最も単純な形を選ぶ。機能を削れという意味ではない。
- 由来:ロッキードのスカンクワークスを率いたケリー・ジョンソンの格言。部下だったベン・リッチの伝記録には「Keep it simple, stupid—KISS—is our constant reminder.」とカンマ付きで記録されている。整備士と工具の逸話は広く流布しているが、この伝記録とロッキード・マーティンの公式人物紹介には載っていない。
- 実践:ネストはガード節で浅くし、場合分けは条件の言い換えで減らし、2択のために抽象化の層を作らない。
- 測り方:循環的複雑度(Ruffの既定上限10、ESLintの既定上限20)と認知的複雑度は分岐とネストを数えるが、余計なクラスや間接化は数えない。指標が低くてもKISS違反はありうる。
- 使い分け:KISS=どう作るか、YAGNI=何を作るか、DRY=同じ知識を2か所に置かない、SOLID=変更に強くする。迷ったらKISSとYAGNIで最小の形を作り、重複や変更が実害になった箇所にだけDRYとSOLIDを当てる。
KISS原則の意味と「単純」の定義
KISSは、同じ結果を出せるなら分岐・ネスト・抽象化の層・依存する部品を減らし、後から読む人が少ない前提で全体を把握できる作りを優先する考え方です。ハッカー文化の用語集The Jargon Fileは、KISSを「なし崩しの機能追加(creeping featurism)を防ぎ、開発の複雑さを抑えるために設計の議論で持ち出される格言」と説明しています(The Jargon File: KISS Principle)。
ここでの「単純」は「機能が少ない」でも「誰でも書ける」でもありません。税計算のように仕様そのものが複雑な処理でも、記述上の分岐は減らせます。ただし、仕様で必要な場合分けや計算条件は省けません。減らすのは、仕様に由来しない複雑さです。
simple(単純)とeasy(簡単・慣れている)の区別
KISSを実務で使うとき、いちばん取り違えやすいのが「単純」と「慣れている」の混同です。Clojureの作者Rich Hickeyは、2011年のStrange Loopでの講演「Simple Made Easy」でこの2語を分けました。講演の公式概要は「問題領域を単純化し、単純な部品を組み合わせて解決策を作るべきだ」と述べています(Strange Loop 2011: Simple Made Easy)。講演の中でHickeyは、simpleの語源を「ひとつの撚り(one fold)」、easyの語源を「近くにある(lie near)」と説明し、simpleは物の構造の性質、easyは使う人の慣れや手近さという相対的な性質だと区別しています(InfoQの講演動画)。
KISSが求めるのはsimpleの方です。チームが見慣れたフレームワークを1つ足すのはeasyですが、依存と設定が増えるならsimpleではありません。レビューで「単純か」を問うときは「慣れているか」ではなく「絡み合った部品が少ないか」を見ます。
ソフトウェア以外での使われ方
KISSは航空機設計から広まった言葉で、UI設計(1画面の選択肢を絞る)、技術文書(1文1論点)、運用手順(障害時に手順を分岐させない)にも使われます。英語版Wikipediaは、アニメーターのRichard Williamsが著書『The Animator’s Survival Kit』で、動かしすぎる新人にKISSを説いた例も挙げています(KISS principle – Wikipedia)。
Keep it simple, stupidの由来とstupidの意味
ケリー・ジョンソンとスカンクワークス:一次資料の記述
KISSと結び付けられているのは、ロッキードの先進開発部門「スカンクワークス」を率い、SR-71ブラックバードなどを設計したクラレンス・L・(ケリー)・ジョンソン(1910〜1990年)です。ロッキード・マーティンの公式人物紹介は、ジョンソンの「好んだ格言」として「KISS—Keep It Simple, Stupid.」を挙げています(Lockheed Martin: Kelly Johnson)。
スカンクワークスでジョンソンの下にいたベン・R・リッチが書いた米国科学アカデミーの伝記録(1995年)では、p.231に「成果をより安く、早く、良くする」「動いているなら直すな」といったジョンソンの言葉と並んで、「Keep it simple, stupid—KISS—is our constant reminder.(「単純にしておけ、ばかもの」—KISS—が我々の常なる戒めだ)」とあります(Ben R. Rich, Clarence Leonard (Kelly) Johnson 1910–1990: A Biographical Memoir)。
一方、日本語の解説で定番になっている2つの話は、この2資料では確かめられません。
- 工具の逸話:「設計チームに工具を一握り渡し、戦場の平均的な整備士がその工具だけで直せるジェット機を作れと命じた」という話は英語版・日本語版Wikipediaに載っていますが、どちらも出典が付いていません。リッチの伝記録とロッキード・マーティンの人物紹介には、整備士(mechanic)や工具の話は出てきません。
- カンマの有無:「ジョンソン本人はカンマなしでKeep it simple stupidと書いた」という説の出典は、英語版Wikipediaでは2004年のITアウトソーシング論文です。上の伝記録はカンマ付きで引用しています。
したがって「stupid」が設計者を罵る語か、壊れ方と直す手段の関係を指す語かは、一次資料からは決められません。確かなのは、ジョンソンがこの言葉をチームの戒めとして使い続けたことです。
1938年・1960年の用例と表記の変形
英語版Wikipediaは、俗語辞典(Tom Dalzell『The Routledge Dictionary of Modern American Slang and Unconventional English』2009年、p.595)を典拠に、KISSを1960年に米海軍が記した設計原則としています。辞典は1960年12月4日付Chicago Daily Tribuneの、ポール・D・ストループ少将が率いた米海軍「Project KISS」を挙げています。日本語版Wikipediaが「1960年代の米国海軍において言われた」とするのはこの系統です(KISSの原則 – Wikipedia)。新聞の原紙面とは照合できていないため、ここでは辞典経由の記録として扱います。
stupidを避けた言い換えも多くあります。
| 表記 | 意味 | 主な使われ方 |
|---|---|---|
| Keep it simple, stupid | 単純にしておけ、ばかもの | 最も一般的な表記 |
| Keep it short and simple | 短く単純に | 文章・話し方の指導 |
| Keep it simple and straightforward | 単純で率直に | ビジネス文書 |
| Keep it simple, silly | 単純にね | stupidの婉曲表現 |
英語版Wikipediaは「Keep It Short and Simple」の用例が1938年のMinneapolis Star紙にあるとしています。原紙面とジョンソンが使い始めた時期を照合できないため、どちらが先かはここでは決めません。現在も、米国ユタ地区連邦裁判所の保護観察部門は面接の心得として「KISS(Keep It Short and Simple)」を掲げています(U.S. Probation and Pretrial Services, District of Utah: Interviewing)。
コードでKISSを実践する書き換え例
ここからは、KISSに沿った書き換えを3つ、Pythonで実行して計測した結果とあわせて示します。計測はPython 3.9.6で、循環的複雑度をradon 6.0.1とlizard 1.24.1、認知的複雑度をflake8-cognitive-complexity 0.1.0(内部でcognitive_complexity 1.3.0を使用)で測りました。このライブラリは作者がSonarSourceの原アルゴリズムの厳密な実装ではないと明記しているため、認知的複雑度の値はこの実装での値です(cognitive_complexity)。関数ごとの循環的複雑度はradonとlizardで一致しました。
ガード節によるネストの削減
前提を満たさないケースを関数の冒頭で先に返す「ガード節」は、正常系をネストの外に出します。
# 変更前:正常系が2段のネストの奥にある
def get_price_nested(user):
if user is not None:
if user["is_member"]:
return user["price"] * 0.9
else:
return user["price"]
return 0
# 変更後:例外ケースを先に返し、本筋を平坦にする
def get_price_guard(user):
if user is None:
return 0
if not user["is_member"]:
return user["price"]
return user["price"] * 0.9
計測すると、循環的複雑度は変更前・変更後とも3で変わりません。分岐の数は同じだからです。下がったのは認知的複雑度で、4から2になりました。認知的複雑度は、制御構造が入れ子になるたびに加点する規則を持つためです(G. Ann Campbell, Cognitive Complexity, Version 1.7)。ガード節は「経路を減らす」技法ではなく「読む順序を平らにする」技法だと押さえておくと、効果を過大評価せずに済みます。言語別の書き方と使うべきでない場面はアーリーリターン(early return)とは?ネストを減らす書き方とガード節・言語別の実装で扱っています。
区間の重なり判定における条件の簡略化
KISSで効果が大きいのは、場合分けを1つずつ書く代わりに、問題を言い換えて条件そのものを短くする書き換えです。開始時刻が終了時刻より前である会議室の予約[s1, e1)と申込[s2, e2)を対象に比較します。s1 < e1、s2 < e2を前提とし、空区間や逆転した区間は呼び出し前に除外します。
def overlaps_branchy(s1, e1, s2, e2):
"""予約[s1, e1)と申込[s2, e2)が重なるか。パターンを列挙した版"""
if s2 < s1:
if e2 <= s1:
return False
else:
return True
elif s2 == s1:
return True
else:
if s2 < e1:
if e2 <= e1:
return True
else:
return True
else:
return False
def overlaps_simple(s1, e1, s2, e2):
"""重ならない条件(どちらかが先に終わる)の否定"""
return s2 < e1 and s1 < e2
if __name__ == "__main__":
n = 0
for s1 in range(13):
for e1 in range(s1 + 1, 13):
for s2 in range(13):
for e2 in range(s2 + 1, 13):
assert overlaps_branchy(s1, e1, s2, e2) == overlaps_simple(s1, e1, s2, e2)
n += 1
print(f"{n}通りの組み合わせで両者の結果が一致")
「重なる」を直接列挙すると、境界(終了時刻と開始時刻が同じ)を含めて分岐が増えます。「重ならないのは、片方がもう片方の開始までに終わるときだけ」と言い換えると、条件は1行になります。0〜12時の整数の区間で全組み合わせを総当たりした結果、6,084通りで両者の結果が一致しました。循環的複雑度は6から2へ、認知的複雑度は9から1へ下がっています。
この書き換えは、総当たりのテストがあったから安全に行えました。条件を短くする書き換えは、境界の扱いを1文字(<と<=)間違えるだけで結果が変わるため、先にテストを書いてから縮めます。
固定送料2種類に対する過剰な抽象化
KISS違反の典型は、分岐ではなく層の多さとして現れます。送料が「通常500円・速達1,200円」の2種類しかないのに、Strategyパターンとファクトリーを用意した例です。
from abc import ABC, abstractmethod
class ShippingStrategy(ABC):
@abstractmethod
def fee(self) -> int: ...
class StandardShipping(ShippingStrategy):
def fee(self) -> int:
return 500
class ExpressShipping(ShippingStrategy):
def fee(self) -> int:
return 1200
class ShippingStrategyFactory:
_registry = {"standard": StandardShipping, "express": ExpressShipping}
@classmethod
def create(cls, kind: str) -> ShippingStrategy:
return cls._registry[kind]()
def shipping_fee_abstract(kind: str) -> int:
return ShippingStrategyFactory.create(kind).fee()
# 同じ仕様を表で持つ版
SHIPPING_FEES = {"standard": 500, "express": 1200}
def shipping_fee_simple(kind: str) -> int:
return SHIPPING_FEES[kind]
空行とコメントを除く物理行で数えると、抽象化した版は4クラス・17行(importとデコレーターを含む)、表で持つ版は3行です。それでも循環的複雑度は全関数・全メソッドが1、認知的複雑度は0で、指標上はどちらも「単純」と判定されます。送料の種類ごとに計算方法がまったく違う、または外部の配送業者APIを差し替える予定が決まっている、という条件がそろってからStrategyに切り替えれば足ります。パターン自体の使いどころはStrategyパターンとは?PHP・Java・TypeScriptの実装例と使いどころを参照してください。
複雑度の指標で測れる単純さ・測れない単純さ
「単純かどうか」をレビューの感覚だけに任せないために、循環的複雑度を上限として設定するチームは多くあります。上限の数字には出典があります。トーマス・マッケイブは1976年の論文「A Complexity Measure」(IEEE Transactions on Software Engineering, SE-2(4), pp.308–320)のp.314で、現場で使った上限10を「合理的ではあるが魔法の数字ではない(reasonable, but not magical)」と書き、多数の独立したケースを並べる大きなcase文は例外として認めていました(McCabe, A Complexity Measure)。マッケイブ自身が共著者のNIST SP 500-235(1996年8月)第2.5節は、15までの上限も成功裏に使われてきたとしつつ、10を超える上限は経験豊富な要員・形式的な設計・コードウォークスルー・包括的なテスト計画などを備えたプロジェクトに限るべきだとしています(NIST SP 500-235 Structured Testing)。
主要なツールの既定値は揃っていません。2026年10月時点の版で、RuffのC901とESLintのcomplexityルールを有効にし、上限値は変更せず、上限ちょうどと上限を1超える関数を検査し、lizardは実行時に表示される既定のしきい値を記録しました。
| ツール(版) | 指標 | 既定で警告する値 |
|---|---|---|
| Ruff 0.17.1(C901) | 循環的複雑度 | 11以上(上限10) |
| ESLint v10.13.0(complexity) | 循環的複雑度 | 21以上(上限20) |
| lizard 1.24.1 | 循環的複雑度 | 16以上(上限15) |
Ruffのmax-complexityの既定10とESLintのcomplexityルールの既定20は、公式ドキュメントの記載とも一致します。ESLintのcomplexityルールを有効にして上限値を変更しなければ、20までは検出されず、21以上で設定した警告またはエラーが出ます。計算方法やツールごとに値が違う理由、しきい値の決め方はサイクロマティック複雑度とは?計算方法・目安10の根拠とツールで値が違う理由で詳しく扱っています。
前章の実測をまとめると、指標が拾うものと拾わないものがはっきり分かれます。
| 書き換え | 循環的複雑度 | 認知的複雑度 | 指標の反応 |
|---|---|---|---|
| ガード節 | 3 → 3 | 4 → 2 | 認知的複雑度だけが下がる |
| 条件の言い換え | 6 → 2 | 9 → 1 | 両方が下がる |
| 抽象化の層を外す | 1 → 1 | 0 → 0 | どちらも反応しない |
結論として、複雑度の上限は「分岐とネストの膨張」を止める柵としては有効ですが、KISSの合否判定には使えません。使われていないインターフェース、1つしか実装の無い抽象クラス、2段以上の委譲は、レビューで人が「この層を外すと何が困るか」を問うしかありません。答えが出ない層は外します。
KISS・DRY・YAGNI・SOLIDの違いと優先順位
KISSはDRY・YAGNI・SOLIDと並べて語られますが、それぞれ問いが違います。
| 原則 | 問い | 主に排除するもの |
|---|---|---|
| KISS | その作りは単純か | 仕様に由来しない複雑さ |
| YAGNI | それは今要るか | 先回りした機能・拡張点 |
| DRY | 同じ知識が2か所にないか | 知識・ロジックの重複 |
| SOLID | 変更が来たとき影響が閉じるか | 変更に弱い依存関係 |
KISSは「どう作るか」の単純さ、YAGNIは「何を作るか」の範囲を扱います。作らないものが増えれば構造も単純になるので、両者は同じ方向を向きます。YAGNIの原典と先回り実装のコストはYAGNI(ヤグニ)原則とは?意味・読み方と先回り実装の4つのコストで整理しています。
衝突しやすいのはDRYとSOLIDです。似た3行を見つけるたびに共通関数へまとめると、引数とフラグが増えて呼び出し側の分岐が複雑になります。似ているだけで変わる理由が違うコードは、重複のまま残す方がKISSに沿います(DRY原則とは?重複してよいコードの見分け方と誤った共通化の避け方)。SOLIDの単一責任の原則はKISSと重なりますが、責務を細かく割りすぎると、1つの処理を追うのに何ファイルも開く構造になります(SRP(単一責任の原則)とは?意味と具体例、SRP違反・やりすぎ(過剰分割)の見極め方)。
迷ったときの順序は、まずKISSとYAGNIで今の要件に対する最小の形を作り、同じ知識を複数箇所で同期して修正する必要が明らかになったらDRYを、変更の影響範囲や依存関係に問題がある箇所にはSOLIDを検討する、です。先にDRYやSOLIDを当てると、まだ来ていない変更のために層を作ることになり、前章の送料の例と同じ形になります。
KISSが逆効果になる場面:単純にしすぎる失敗
KISSを「短く書け」「機能を減らせ」と読み違えると品質を落とします。次の場面では単純化をそのまま進めません。
- 仕様そのものの複雑さを削る:税計算や権限判定のように、仕様が持つ分岐を短く書こうとして条件を落とすと、バグになります。減らすのは記述の複雑さで、必要な分岐ではありません。
- コピーを単純さと取り違える:同じロジックを各所に貼ると、どの箇所も短く見えますが、仕様変更で修正漏れが出ます。これはeasy(手近)であってsimpleではありません。
- 決まっている変更軸を捨てる:来月に決済手段が増えると決まっている箇所をベタ書きにすると、改修が毎回大きくなります。KISSは「今わかっている要件に対して最小」であり、確定した要件への備えまで削ることではありません。
- 1行に詰め込む:内包表記や三項演算子を重ねて行数を減らしても、読む人が頭の中で展開する量は減りません。前章の重なり判定が1行で済んだのは、条件そのものが短くなったからです。
「何事もできる限り単純にすべきだ。ただし、単純すぎてはいけない」という言葉がアインシュタインのものとしてよく引かれます。名言の出典を調べるQuote Investigatorが挙げる最も古い用例は、1950年1月8日のニューヨーク・タイムズに作曲家ロジャー・セッションズが「要するに(in effect)」と断って紹介した言い換えです。これに対してアインシュタイン自身の文は1933年6月10日のオックスフォードでの講演の「理論の究極の目標は、経験のどのデータも適切に表すことを手放さずに、還元できない基本要素をできるだけ単純かつ少なくすることだ」という一節です(Quote Investigator: Everything Should Be Made as Simple as Possible, But Not Simpler)。KISSの限界を表すのは、引用されがちな短い言い換えよりも、この講演の「データを手放さずに」という条件の方です。
よくある質問
KISSの法則とKISSの原則は同じ意味ですか?
同じものです。英語のKISS principleの訳で、「KISS原則」「KISSの原則」「KISSの法則」のいずれも使われます。読み方は「キス」です。
Keep it simple, stupidのstupidは失礼な意味ですか?
字義は「ばかもの」で、作業者を見下す意味ではないという解釈が日本語の解説で広く紹介されていますが、その根拠とされる整備士と工具の逸話には出典が確認できません。ジョンソンの部下ベン・リッチの伝記録では、チームの「常なる戒め」として記録されています。気になる場面では「Keep it short and simple」などの言い換えが使われます。
KISS原則とYAGNI原則の違いは何ですか?
KISSは「どう作るか」を単純にする指針、YAGNIは「今必要ない機能を先回りして作らない」という範囲の指針です。作らないものが増えると構造も単純になるため、YAGNIはKISSを実現する手段の一つになります。
KISSとDRY・SOLIDが衝突したときはどれを優先しますか?
今の要件に対してはKISSとYAGNIで最小の形を作り、同じ知識の同期修正が必要ならDRY、変更の影響範囲や依存関係に問題があればSOLIDを検討します。まだ起きていない重複や変更のために抽象化を足すと、KISSに反します。
Keep it short and simpleとKISSは同じですか?
同じ頭文字の言い換えで、意図はほぼ同じです。stupidを避けた表現として文章や話し方の指導でよく使われ、米国の連邦裁判所の保護観察部門も面接の心得として「KISS(Keep It Short and Simple)」を掲げています。設計原則としてはKeep it simple, stupidの表記が一般的です。