📝

Delegates.observable と Getter/Setter の違い

2024/11/27に公開

はじめに

ChatGPT先生に聞いてみました。
Kotlin を使う中で、プロパティの変更を管理・追跡する場面は少なくありません。その際によく使われるのが Delegates.observablegetter / setter です。それぞれの特性を理解して使い分けることで、より効率的なコードが書けます!この記事では、この2つの違いをわかりやすく解説します。


Delegates.observable とは?

Delegates.observableプロパティの変更を監視するためのツール です。プロパティの値が変更されるたびに、指定したコールバック関数が呼び出されます。これにより、プロパティ変更時の副作用を簡潔に記述できます。

主な特徴

  • プロパティが 変更されるたびにコールバック関数 が呼び出される。
  • oldValue(変更前の値)と newValue(変更後の値)を取得可能。
  • プロパティ変更時にロジックを追加したい場合に最適。

構文

var property by Delegates.observable(initialValue) { property, oldValue, newValue ->
    // プロパティが変更されたときの処理
}

使用例

import kotlin.properties.Delegates

var age: Int by Delegates.observable(0) { property, oldValue, newValue ->
    println("${property.name} changed from $oldValue to $newValue")
}

fun main() {
    age = 25  // 出力: age changed from 0 to 25
    age = 30  // 出力: age changed from 25 to 30
}

Getter / Setter とは?

getter / setterプロパティの取得時や設定時に特定の処理を追加 するために使用します。通常のプロパティにカスタムロジックを実装したい場合に役立ちます。

主な特徴

  • getter: プロパティ取得時のカスタムロジックを定義。
  • setter: プロパティ設定時のカスタムロジックを定義。
  • 値のバリデーションやカスタム状態管理に最適。

構文

var property: Type
    get() { ... } // 値取得時の処理
    set(value) { ... } // 値設定時の処理

使用例

var age: Int = 0
    set(value) {
        if (value >= 0) {
            field = value // `field` はバックフィールド
            println("Age updated to $value")
        } else {
            println("Invalid age value: $value")
        }
    }

fun main() {
    age = 25  // 出力: Age updated to 25
    age = -5  // 出力: Invalid age value: -5
}

違いを比較

特徴 Delegates.observable Getter / Setter
適用範囲 プロパティの変更を監視するための専用ツール プロパティの取得や設定時に特定の処理を挟むためのツール
変更前後の値の取得 oldValuenewValue を簡単に取得できる 直接は取得できないが、カスタムロジックで可能
使用例 ログ出力や UI 更新通知など、プロパティ変更時の副作用を簡潔に記述 値のバリデーションやカスタム取得処理など
再利用性 デリゲートなので複数プロパティに同じ処理を簡単に適用可能 再利用するには抽象化が必要
コールバックの頻度 常に呼び出される (変更時のみ) 必要に応じてカスタム設定

まとめ

  • Delegates.observable: プロパティ変更時の「通知や追跡」が必要な場合に適しています。
  • Getter / Setter: プロパティの「値の管理や制御」が必要な場合に便利です。

Discussion