0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【リファクタリング】Separate Query from Modifier(照会と変更の分離)

Posted at

1. 概要(Overview)

Separate Query from Modifier は、
データを取得するメソッド(Query)オブジェクトの状態を変更するメソッド(Modifier) を分離するリファクタリングです。

1つのメソッドが「値を返す」と同時に「状態を変更する」ことは、副作用が隠れてバグを生みやすくします。
「値を返すメソッドは副作用を持たない」というルールを守ることで、コードの可読性・テスト容易性が向上します。

目的は以下の通りです:

  • 副作用をなくして予測可能な設計にする
  • 呼び出し側の混乱を防ぐ(値を取るだけなのか、状態も変わるのか?)
  • 関数型プログラミング的な「純粋さ」に近づける

2. 適用シーン(When to Use)

  • 値を返すメソッドが内部状態を変更している
  • 「このメソッドは読んでいるだけ?」と疑問を持たせるようなコードがある
  • テストで「値取得しただけなのに、副作用で状態が変わる」ために不具合が起きている

よくある匂い:

  • Side Effects(副作用のあるメソッド)
  • Inconsistent Method(用途が混在しているメソッド)

3. 手順(Mechanics / Steps)

  1. 値を返すと同時に副作用を持っているメソッドを特定
  2. 副作用部分(状態変更)を別のメソッドに切り出す
  3. 元のメソッドは純粋に「値を返す」だけにする
  4. 呼び出し側コードを修正し、必要なら両方のメソッドを明示的に呼び出す

4. Kotlin 例(Before → After)

Before:取得メソッドが副作用を持つ

class Counter {
    private var count = 0

    fun getNext(): Int {
        count++        // ← 状態を変更している
        return count   // 値も返している
    }
}

fun main() {
    val counter = Counter()
    println(counter.getNext()) // 1
    println(counter.getNext()) // 2
}
  • getNext() は「次の値を返す」と同時に「内部状態を更新」している
  • 「取得」と「変更」が混ざっており、呼び出しの意図が不明確

After:照会と変更を分離

class Counter {
    private var count = 0

    fun getCount(): Int = count   // 照会専用(副作用なし)

    fun increment() {             // 変更専用
        count++
    }
}

fun main() {
    val counter = Counter()
    counter.increment()
    println(counter.getCount()) // 1
    counter.increment()
    println(counter.getCount()) // 2
}
  • getCount() は純粋に状態を返すだけ
  • increment() は副作用(状態変更)のみを担う
  • 呼び出しの意図が明確になった

5. 効果(Benefits)

  • メソッドの役割が明確になり、可読性が向上
  • テストが簡単になる(「照会だけ」「変更だけ」を切り分けられる)
  • 呼び出し側の意図が分かりやすくなる(「値を取るのか」「状態を変えるのか」)
  • 関数型スタイルに近づき、副作用の予測が容易になる

6. 注意点(Pitfalls)

  • 分離により「呼び出し回数」が増えるため、パフォーマンスに影響する可能性がある(通常は無視できる)
  • 外部 API とのインタラクション(例:DB の getAndUpdate)では、分離が難しい場合もある
  • ドメインによっては「照会と更新が一体」な方が自然なこともある

まとめ

  • Separate Query from Modifier は「照会(値を返す)と変更(副作用)を分ける」リファクタリング
  • 判断基準:このメソッドは「読む」だけか? 「書く」もしているか?
  • 基本思想:呼び出し側に「副作用の有無」を明確に伝え、予測可能なコードにする

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?