「設計って難しいな…」
そう感じたこと、きっと一度や二度ではないはずです。
SOLID 原則は有名ですが、実際の現場ではそこまで厳密に意識していないことも多いですよね。
むしろ、もっとシンプルで、日常的に効く原則のほうが役に立つ場面は多いです。
そこで今回は DRY、KISS、YAGNI といった “今日から使える設計のコツ” を、肩の力を抜いて紹介します。
難しい理屈よりも、実際にコードを書くときに思い出せるような内容を中心にまとめました。
DRY(Don't Repeat Yourself)
「同じことを何度も書くのはやめよう」 という、あまりにも有名な原則です。
ただ、DRY は単なる「コピペ禁止」ではありません。
私が意識しているのは、“知識の重複をなくす” という点です。
- バリデーションが複数箇所に散らばっている
- 同じロジックがサービス層とコントローラ層に両方ある
- 設定値があちこちにハードコードされている
こうした状態は、後から修正するときに地獄を見ます。
「どこを直せば全部に反映されるんだっけ…?」と迷子になるやつです。
C#で見る DRY の例
❌ DRY違反(同じバリデーションが2箇所)
public bool IsValidUser(string name, int age)
{
if (string.IsNullOrWhiteSpace(name) || age < 0)
{
return false;
}
return true;
}
public bool IsValidAdmin(string name, int age)
{
if (string.IsNullOrWhiteSpace(name) || age < 0)
{
return false;
}
return true;
}
✅ DRYを守る(共通化)
public bool IsValidPerson(string name, int age)
{
return !string.IsNullOrWhiteSpace(name) && age >= 0;
}
ポイント
- 「知識の重複」をなくすと、変更が一箇所で済む
- 修正漏れが起きにくくなる
- コードの意図が明確になる
KISS(Keep It Simple, Stupid)
KISS は 「シンプルにしようよ」 という、開発者にとっての優しいおまじないです。
複雑なコードって、書いているときは「俺、天才か?」と思うんですが、
数週間後に読み返すと「誰だよこれ書いたの…」と自分にキレる羽目になります。
KISS の本質は、“短くする”ことではなく、“意図が明確で読みやすい構造にする”ことです。
C#で見る KISS の例(構造をシンプルにする)
❌ KISS違反(条件が複雑で読みにくい)
public bool CanAccess(User user)
{
if ((user.Role == "Admin" && user.IsActive) ||
(user.Role == "Manager" && user.IsActive && !user.IsSuspended))
{
return true;
}
return false;
}
✅ KISSを守る(段階的に条件を整理)
public bool CanAccess(User user)
{
if (!user.IsActive) return false;
return user.Role == "Admin" ||
(user.Role == "Manager" && !user.IsSuspended);
}
ポイント
- 条件を段階的に分けることで読みやすくなる
- 「何をチェックしているのか」が一目でわかる
- シンプルさは“理解しやすさ”につながる
YAGNI(You Aren't Gonna Need It)
YAGNI は 「それ、どうせ使わないよ」 という、ちょっと辛辣だけど真実を突く原則です。
未来の要件を想像して、つい余計な機能を作り込んでしまうことってありますよね。
でも、実際には使われないまま放置されることがほとんどです。
- 「将来必要になるかも」で作った拡張ポイント
- 使われない設定項目
- まだ使わない抽象化
こうした“未来への投資”は、たいてい回収されません。
むしろ、コードを複雑にしてメンテコストを増やす負債になります。
C#で見る YAGNI の例
❌ YAGNI違反(未来のために余計なメソッドを追加)
public interface IUserRepository
{
void Save(User user);
void SaveWithLogging(User user); // まだ使わない
void SaveWithTransaction(User user); // まだ使わない
}
public class UserRepository : IUserRepository
{
public void Save(User user) { /* ... */ }
public void SaveWithLogging(User user) { /* ... */ }
public void SaveWithTransaction(User user) { /* ... */ }
}
✅ YAGNIを守る(必要なものだけ)
public interface IUserRepository
{
void Save(User user);
}
public class UserRepository : IUserRepository
{
public void Save(User user) { /* ... */ }
}
ついでに紹介したい、他の便利な原則たち
SoC(Separation of Concerns)
関心ごとを分離しよう、という原則。
UI とロジック、ドメインとインフラなど、役割を分けることでコードが整理されます。
SLAP(Single Level of Abstraction Principle)
1つの関数の中で、抽象度を揃えようという考え方。
「細かい処理」と「大きな流れ」が混ざると読みづらくなるので、関数を分けるとスッキリします。
最小驚愕の原則(Principle of Least Astonishment)
読んだ人が「えっ?」と驚かないコードを書こう、というもの。
命名や挙動を“自然”にすることで、理解しやすいコードになります。
まとめ:設計原則は“守るため”ではなく“楽をするため”にある
設計原則って、守らなきゃいけないルールというより、
「開発を楽にするための知恵」 なんですよね。
- DRY → 変更が楽になる
- KISS → 読むのが楽になる
- YAGNI → 作るのが楽になる
どれも、未来の自分やチームを助けるためのものです。
SOLID ももちろん大事ですが、
まずは今回紹介したようなシンプルな原則を意識するだけで、
コードの質は驚くほど変わります。
今日からの開発が、少しでもラクになりますように。