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?

【リファクタリング】第31回 Duplicate Observed Data(重複した観測データ)

Last updated at Posted at 2025-09-17

はじめに

リファクタリングの悪臭の一つに Duplicate Observed Data(重複した観測データ) があります。
これは 同じデータを複数の場所で保持し、更新のたびに同期処理が必要になる状態 を指します。

一見便利そうに見えますが、バグや不整合の温床になりやすく、保守性を大きく下げる要因となります。


31.1 特徴

  • ドメインオブジェクトと UI(フォーム、ViewModel)が同じデータを保持
  • 変更時に「片方だけ更新される」ケースが発生
  • 同期処理が散在し、コードが煩雑化
  • 「どちらが正しい値か」分からなくなる

31.2 なぜ問題か?

  • 同期忘れによる不整合 が発生
  • コードの重複(load / save のようなメソッド)が増加
  • データフローが複雑になり、デバッグが困難になる

31.3 解決手法

  • Observer パターン:データを1箇所で持ち、変更時に通知
  • MVVM アーキテクチャ:Model が唯一の真実のソース(Single Source of Truth)
  • 重複削除:不要なフィールドは潔く削除

31.4 Kotlin 例

Before:重複した観測データ

class Customer(var name: String)

class CustomerForm {
    var name: String = ""

    fun loadFromCustomer(customer: Customer) {
        this.name = customer.name
    }

    fun saveToCustomer(customer: Customer) {
        customer.name = this.name
    }
}
  • CustomerCustomerForm が両方 name を保持
  • loadFromCustomer / saveToCustomer で同期が必要 → 更新忘れのリスク

After①:Observer パターンで同期

class Customer(var name: String) {
    private val listeners = mutableListOf<(String) -> Unit>()

    fun addNameListener(listener: (String) -> Unit) {
        listeners.add(listener)
    }

    fun updateName(newName: String) {
        name = newName
        listeners.forEach { it(newName) }
    }
}

class CustomerForm(customer: Customer) {
    var displayedName: String = customer.name

    init {
        customer.addNameListener { newName ->
            displayedName = newName
            println("Form updated: $displayedName")
        }
    }
}

→ データは Customer が唯一保持。Form は変更を監視するだけ。


After②:MVVM 的アプローチ

data class Customer(val name: String)

class CustomerViewModel {
    var customer: Customer = Customer("Taro")
        private set

    fun updateName(newName: String) {
        customer = customer.copy(name = newName)
    }
}

→ ViewModel が「Single Source of Truth」となり、UI はこれを監視。


31.5 実務での指針

  • データは 一箇所に集約(Single Source of Truth)
  • UI とドメインで同じフィールドを持たないようにする
  • Kotlin / Android では StateFlow / LiveData / Compose State を活用
  • 同期処理は極力自動化し、手動の load/save を排除する

まとめ

  • Duplicate Observed Data は「同じデータを複数箇所に持ち、同期が必要になる」悪臭
  • 解決策は Observer パターン / MVVM / 重複削除
  • 基本思想「データは1箇所に。UIや他の層はそれを監視するだけ」

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?