Kotlin / Programming

ザクっと理解するKotlinで見るカプセル化

オブジェクト指向プログラミングの基礎であるカプセル化は、コードの品質を高める重要な要素の1つです。

Kotlinのコード例を交えながら、本記事ではカプセル化の基礎から利点までを解説します。

再利用性、柔軟性、簡素化など、カプセル化がもたらすメリットを理解する助けになればと思います!

カプセル化とは

カプセル化とはクラスの外部から参照、操作を直接できないようにし、ゲッターやセッターなどのインターフェースを通してのアクセスのみを可能にします。

こうすることで意図しない値の書き込みや読み取りを防ぎ、保守性の高いコードを書くことです。

カプセル化の利点

情報隠蔽、柔軟性、再利用性、インターフェースの簡素化があります。

簡単なKotlinコードを使いながら順番に見ていきましょう。

情報隠蔽

情報隠蔽とはクラスの内部の情報を隠蔽し、外部からアクセスできないようにすることで、プログラムの信頼性を高め、バグの発生を防止することです。

これを初めて読んだ時はさっぱりでした。

ということでまずはこちらのコードを見てみます。

class Person() {
    var firstName = ""
    var lastName = ""
    
    fun changeFirstName(newFirstName: String) {
        firstName = newFirstName
    }
    
    fun changeLastName(newLastName: String) {
        lastName = newLastName
    }
    
    fun getName() = firstName + " " + lastName
}

このクラスは

・chageFirstName関数とchangeLastName関数を使いプロパティの値を変更すること

・名前の取得はgetNameで行うこと

を意図して作成されています。

しかしカプセル化の原則を無視しているため、この意図通りに使用されないケースが考えられます。

例えばこのように値の書き換えや参照がされる可能性があります。

fun main() {
    val person = Person()
    person.firstName = "John"
    person.lastName = "Watt"
    println(person.firstName) // John
    println(person.lastName) // Watt
}

直接の編集や「名 姓」以外での名前の取得は想定されていませんが、実際はできてしまいます。

これにより不整合が発生する可能性やコードの一貫性が保たれない可能性があります。

今度はカプセル化したコードです。

class Person() {
    private var firstName = ""
    private var lastName = ""
    
    fun changeFirstName(newFirstName: String) {
        firstName = newFirstName
    }
    
    fun changeLastName(newLastName: String) {
        lastName = newLastName
    }
    
    fun getName() = firstName + " " + lastName
}

前回との違いはプロパティのpublicをprivateに設定したところです。

そのためプロパティの値の変更と名前の取得はこのようになります。

fun main() {
    val person = Person()
    
    // person.firstName = "John" // エラー
    // person.lastName = "Watt" // エラー
    // println(person.firstName) // エラー
    // println(person.lastName) // エラー
    
    person.changeFirstName("John")
    person.changeLastName("Watt")
    println(person.getName()) // John Watt
}

publicで用意された関数(インターフェース)を通さないと値の上書きと取得ができません。

これにより意図しない情報の上書きや取得を防ぐことができます。

柔軟性

柔軟性とは仕様変更等によるコード変更に対する対応のしやすさを指します。

上のPersonクラスで考えてみます。

例えば、仕様変更等でgetName()で返す内容が「名 姓」から「名-姓」に変更が必要になったとします。

class Person() {
    private var firstName = ""
    private var lastName = ""
    
    fun changeFirstName(newFirstName: String) {
        firstName = newFirstName
    }
    
    fun changeLastName(newLastName: String) {
        lastName = newLastName
    }
    
    // 変更前
    // fun getName() = firstName + " " + lastName
    
    // 変更後
     fun getName() = firstName + "-" + lastName
}

このようにカプセル化をしていれば、getNameの中身を書き換えるだけで済みます。

そのため影響範囲が狭く、柔軟性が高いコードと言えます。

再利用性

上の情報隠蔽と柔軟性により、他アプリケーションなどでもそのまま、あるいは修正を加えて使用できるということです。

インターフェースの簡素化

今までの例のように、プロパティをprivateに設定し必要な関数のみをpublicで宣言することで他クラスからは不要な部分が見えずわかりやすいということです。

これによって、クラスを使用する側のコードがシンプルになり、クラスの変更に強く、保守性が高くなります。

終わりに

カプセル化は、オブジェクト指向プログラミングの基礎であり、コードの品質を高めるために欠かせない要素の1つです。

本記事では、Kotlinを使った実践的なコード例を交えながら、カプセル化の基礎から利点までを解説しました。

再利用性、柔軟性、簡素化など、カプセル化がもたらすメリットを理解する助けになればと思います!

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です