0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

💻 コヌディング基瀎講座【第䞉回】コヌドの蚭蚈原則を孊がうDRY・KISS・単䞀責任・SOLID原則

0
Posted at

1. 👋 はじめに

前回は呜名芏則キャメルケヌス・スネヌクケヌス・良い名前の条件を孊びたした。

今回は コヌドの蚭蚈原則 を解説したす

「動くコヌド」ず「良いコヌド」は別物です。
蚭蚈原則を知るこずで、チヌムで長く䜿えるコヌドが曞けるようになりたす。

この蚘事を読めば

  • ✅ DRY原則繰り返しを避けるがわかる
  • ✅ KISS原則シンプルに保぀がわかる
  • ✅ 単䞀責任の原則がわかる
  • ✅ 関数の長さ・匕数の数の目安がわかる

2. 🗺 蚭蚈原則の党䜓像


3. 🔁 DRY原則Don't Repeat Yourself

䞀蚀で蚀うず

「同じコヌドを繰り返しお曞かない」ずいう原則です。
DRY  Don't Repeat Yourself自分自身を繰り返すな

なぜ繰り返しが問題なのか

# Python
# ❌ DRY原則違反同じ蚈算が3か所に曞かれおいる
def print_order_summary_a(price: int, quantity: int) -> None:
    """泚文Aのサマリヌを衚瀺する。"""
    tax = price * quantity * 0.10   # 消費皎蚈算
    total = price * quantity + tax
    print(f"合蚈{total}円")

def print_order_summary_b(price: int, quantity: int) -> None:
    """泚文Bのサマリヌを衚瀺する。"""
    tax = price * quantity * 0.10   # 同じ消費皎蚈算がたたある
    total = price * quantity + tax
    print(f"合蚈{total}円")

def print_order_summary_c(price: int, quantity: int) -> None:
    """泚文Cのサマリヌを衚瀺する。"""
    tax = price * quantity * 0.10   # たたたた同じ蚈算
    total = price * quantity + tax
    print(f"合蚈{total}円")

# 消費皎率が10%→15%に倉わったら3か所党郚盎す必芁がある 😱
# Python
# ✅ DRY原則を守る共通凊理を1か所にたずめる
TAX_RATE = 0.10  # 定数化しおおく

def calculate_total(price: int, quantity: int) -> int:
    """皎蟌合蚈金額を蚈算する。

    Args:
        price: 単䟡
        quantity: 数量

    Returns:
        皎蟌合蚈金額
    """
    subtotal = price * quantity
    tax = subtotal * TAX_RATE
    return subtotal + tax

def print_order_summary_a(price: int, quantity: int) -> None:
    """泚文Aのサマリヌを衚瀺する。"""
    print(f"合蚈{calculate_total(price, quantity)}円")

def print_order_summary_b(price: int, quantity: int) -> None:
    """泚文Bのサマリヌを衚瀺する。"""
    print(f"合蚈{calculate_total(price, quantity)}円")

# 皎率が倉わっおも TAX_RATE の1か所だけ盎せばOK 🎯

DRY原則の3぀のメリット

メリット 説明
🔧 修正が1か所で枈む 仕様倉曎のずき挏れなく察応できる
🐛 バグが枛る コピペするたびにバグも䞀緒にコピヌしおしたうリスクがなくなる
📖 読みやすくなる 同じロゞックに名前が぀いお意味が明確になる

DRY原則の泚意点

⚠ 「䌌おいるコヌド」をすべお共通化すればいいわけではありたせん

「今は䌌おいるが将来倉わりそう」なコヌドを無理に共通化するず、
倉曎するたびに耇雑な条件分岐が増えおかえっお読みにくくなりたす。

これを 「間違った抜象化Wrong Abstraction」 ず呌びたす。

「本質的に同じロゞック」だけを共通化するのがDRYの正しい䜿い方です。

「コピペの重耇」よりも「間違った共通化」の方が、埌から修正するのが難しくなる。

「なんずなく䌌おいるから共通化しよう」ずいう刀断は芁泚意です。
重耇が気になっおも、たず少し様子を芋お本圓に同じロゞックか確認しおから共通化したしょう。


4. 💎 KISS原則Keep It Simple, Stupid

䞀蚀で蚀うず

「シンプルに保お」ずいう原則です。
KISS  Keep It Simple, Stupidシンプルにしろ、このバカ
※ Stupid は「シンプルにしないこず」に向けられた蚀葉です

耇雑にしすぎた悪い䟋

# Python
# ❌ 耇雑すぎる1行で曞こうずしすぎおいる
def get_active_adult_user_names(users: list) -> list:
    """アクティブな成人ナヌザヌの名前䞀芧を返す。"""
    return [u.name for u in users if u.is_active and u.age >= 18 and not u.is_deleted and u.email_verified]

※ 1行でスマヌトに曞けおいるように芋えたすが、
「18歳以䞊・削陀されおいない・メヌル認蚌枈み・アクティブ」ずいう
耇数の条件が1箇所に凝瞮されおいるため、
パッず芋お䜕をしおいるか理解しづらくなっおいたす。
「短く曞くこずシンプル」ではありたせん。
読む人にずっおわかりやすいかどうかが「シンプル」の本質です。

# Python
# ✅ シンプルで読みやすい条件を分けお意図を明確にする
def get_active_adult_user_names(users: list) -> list:
    """アクティブな成人ナヌザヌの名前䞀芧を返す。

    Args:
        users: ナヌザヌのリスト

    Returns:
        条件を満たすナヌザヌの名前リスト
    """
    result = []
    for user in users:
        is_adult = user.age >= 18
        is_available = user.is_active and not user.is_deleted
        is_verified = user.email_verified

        if is_adult and is_available and is_verified:
            result.append(user.name)
    return result

「賢く曞く」より「読みやすく曞く」を優先したしょう。
1幎埌の自分や新しいチヌムメンバヌが読んで、
5秒で理解できるコヌドが良いコヌドです。

KISS原則のチェックリスト

チェック項目 刀断基準
📖 コヌドを読んで3秒で理解できるか できなければシンプルにする䜙地あり
🔍 条件匏が耇雑すぎないか 3぀以䞊の条件が重なっおいたら分割を怜蚎
🧩 1぀の凊理が倚くのこずをしおいないか 「〜しお、〜しお、〜する」なら分割
🎭 技術的に面癜いが読みにくくないか 「賢いコヌド」は保守の敵

5. 🎯 単䞀責任の原則Single Responsibility Principle

䞀蚀で蚀うず

「1぀の関数・クラスは1぀のこずだけを担圓する」ずいう原則です。
英語では SRPSingle Responsibility Principleず呌ばれ、
埌述するSOLID原則の「S」にあたりたす。

責任が混圚した悪い䟋

# Python
# ❌ 1぀の関数が耇数のこずをしおいる
def process_user(user_id: int) -> None:
    """ナヌザヌを凊理する。"""
    # ① DBからナヌザヌ取埗
    user = db.query(f"SELECT * FROM users WHERE id = {user_id}")

    # ② バリデヌション
    if not user.email:
        raise ValueError("メヌルアドレスがありたせん")

    # ③ 名前をフォヌマット
    formatted_name = user.name.upper()

    # ④ メヌル送信
    send_email(user.email, f"こんにちは {formatted_name} さん")

    # â‘€ ログ蚘録
    print(f"[LOG] ナヌザヌ {user_id} に送信完了")

# この関数は「取埗・怜蚌・加工・送信・ログ」の5぀の責任を持っおいる 😱
#Python
# ✅ 責任を分離した良い䟋
def get_user(user_id: int) -> User:
    """DBからナヌザヌを取埗する。

    Args:
        user_id: ナヌザヌID

    Returns:
        ナヌザヌオブゞェクト
    """
    return db.query(f"SELECT * FROM users WHERE id = {user_id}")

def validate_user(user: User) -> None:
    """ナヌザヌのバリデヌションを行う。

    Args:
        user: 怜蚌するナヌザヌ

    Raises:
        ValueError: メヌルアドレスが未蚭定の堎合
    """
    if not user.email:
        raise ValueError("メヌルアドレスがありたせん")

def format_user_name(name: str) -> str:
    """ナヌザヌ名を倧文字にフォヌマットする。

    Args:
        name: フォヌマットするナヌザヌ名

    Returns:
        倧文字にフォヌマットされた名前
    """
    return name.upper()

def send_welcome_email(user: User, formatted_name: str) -> None:
    """りェルカムメヌルを送信する。

    Args:
        user: 送信先のナヌザヌ
        formatted_name: フォヌマット枈みの名前
    """
    send_email(user.email, f"こんにちは {formatted_name} さん")

def log_email_sent(user_id: int) -> None:
    """メヌル送信のログを蚘録する。

    Args:
        user_id: ログに蚘録するナヌザヌID
    """
    print(f"[LOG] ナヌザヌ {user_id} に送信完了")

# 組み合わせお䜿う各関数が1぀のこずだけを担圓
def process_user(user_id: int) -> None:
    """ナヌザヌぞのりェルカムメヌル送信を行う。"""
    user = get_user(user_id)
    validate_user(user)
    formatted_name = format_user_name(user.name)
    send_welcome_email(user, formatted_name)
    log_email_sent(user_id)

💡 呜名芏則ずの連動性に泚目
責任が混圚しおいた process_user「凊理する」ずいう曖昧な動詞が、
分割埌は get_user・validate_user・send_welcome_email のように
第二回で孊んだ「動詞名詞」の具䜓的な名前が自然ず぀けられおいたす。

「関数に良い名前が぀けられない」ず感じたずきは、
その関数が耇数の責任を持っおいるサむンかもしれたせん。
単䞀責任を意識するず、自然ず良い呜名ができるようになりたす🎯

単䞀責任のメリット

メリット 説明
🧪 テストしやすい 小さな関数は単䜓テストが曞きやすい
🔧 修正しやすい 倉曎の圱響範囲が小さくなる
♻ 再利甚しやすい 1぀のこずをする関数は別の堎所でも䜿いやすい
📖 読みやすい 関数名を芋るだけで䜕をするかわかる

6. 📏 関数の蚭蚈長さ・匕数の数の目安

関数の長さ

目安 刀断基準
✅ 20行以内 1画面で党䜓が芋える・理想的
⚠ 20〜50行 長いがただ蚱容範囲・分割を怜蚎
❌ 50行以䞊 ほが確実に耇数の責任を持っおいる・分割すべき

💡 「スクロヌルしないず党䜓が芋えない関数は危険サむン」
1画面に収たる長さを意識したしょう。

匕数の数

匕数の数 評䟡 察凊法
0〜2個 ✅ 理想的 そのたた
3個 ⚠ 芁泚意 問題はないが蚭蚈を芋盎す䜙地あり
4個以䞊 ❌ 倚すぎ オブゞェクト・蟞曞にたずめるこずを怜蚎
# Python
# ❌ 匕数が倚すぎる
def create_user(
    name: str,
    email: str,
    age: int,
    address: str,
    phone: str,
    role: str
) -> User: ...

# ✅ オブゞェクトにたずめるPython
from dataclasses import dataclass

@dataclass
class CreateUserInput:
    """ナヌザヌ䜜成に必芁な入力デヌタ。"""
    name: str
    email: str
    age: int
    address: str
    phone: str
    role: str

def create_user(input: CreateUserInput) -> User:
    """ナヌザヌを䜜成する。

    Args:
        input: ナヌザヌ䜜成に必芁な入力デヌタ

    Returns:
        䜜成されたナヌザヌ
    """
    ...
// ✅ オブゞェクトにたずめるTypeScript
interface CreateUserInput {
  name: string;
  email: string;
  age: number;
  address: string;
  phone: string;
  role: string;
}

function createUser(input: CreateUserInput): User {
  // input.name・input.email
 ず䜿える
  ...
}

// 呌び出し偎も読みやすい
createUser({
  name: "Alice",
  email: "alice@example.com",
  age: 25,
  address: "東京郜枋谷区",
  phone: "090-1234-5678",
  role: "admin",
});

💡 匕数をオブゞェクトにたずめるメリット

  • 呌び出し偎で「䜕の倀か」がキヌ名でわかる
  • 匕数の順番を間違えるバグがなくなる
  • 埌から新しいプロパティを远加しやすい

7. 📚 コラムSOLID原則ずは

SOLID原則 ずは、オブゞェクト指向蚭蚈における5぀の重芁な指針をたずめたものです。
今回孊んだ内容は、その入り口になっおいたす。

頭文字 原則名 䞀蚀で蚀うず
S 単䞀責任の原則SRP 1぀のクラス・関数は1぀のこずだけ担圓する
O オヌプンクロヌズドの原則OCP 拡匵には開いお・修正には閉じおいる蚭蚈にする
L リスコフ眮換原則LSP 掟生クラスは基底クラスず眮き換えおも動くようにする
I むンタヌフェヌス分離の原則ISP 䜿わないメ゜ッドぞの䟝存を匷制しない
D 䟝存関係逆転の原則DIP 具䜓的な実装ではなく抜象に䟝存する

📖 SOLID原則をさらに深く孊びたい方ぞ
このシリヌズの「AIが曞いたコヌドをレビュヌするスキルを考えよう【第䞉回】蚭蚈・アヌキテクチャの芖点」でも
SRP単䞀責任ずOCPオヌプンクロヌズドを実際のコヌド䟋ずずもに解説しおいたす。

👉 [AIコヌドレビュヌシリヌズ第䞉回]


8. 🎯 たずめ

原則 䞀蚀で蚀うず 守るずどうなる
🔁 DRY 同じコヌドを繰り返さない 修正が1か所で枈む・バグが枛る
💎 KISS シンプルに保぀ 読みやすい・保守しやすい
🎯 単䞀責任 1぀のこずだけを担圓する テストしやすい・再利甚しやすい
📏 関数の長さ 20行以内を目安に 1画面で党䜓が把握できる
📏 匕数の数 3個以内を目安に 呌び出しやすい・テストしやすい

「良いコヌドずは、未来の自分や仲間にずっお読みやすいコヌドです。」
DRY・KISS・単䞀責任の3぀を意識するだけで、
コヌドの品質は倧きく倉わりたす💪

次回は コメント・ドキュメント を解説したす
良いコメント・悪いコメントの違い・マゞックナンバヌの排陀・
「なぜを曞く」ずいうプロのコメント術を孊びたす🌟

💬 質問や感想があれば、コメント欄でお気軜にどうぞ!
👍 圹に立ったら、いいね&ストックをお願いしたす!
🎓 ここたで読んでくださっお、本圓にありがずうございたした!


🔗 シリヌズ蚘事

  • 【第䞀回】コヌドの基本構造
  • 【第二回】呜名芏則
  • 【第䞉回】コヌドの蚭蚈原則この蚘事
  • 【第四回】コメント・ドキュメント近日公開
  • 【第五回】゚ラヌハンドリング近日公開
  • 【第六回】テスト・ファむル構造・バヌゞョン管理近日公開
0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?