okuzawatsの日記

Android / Kotlin Enthusiast 🤖

自己カプセル化

自己カプセル化(Self-Encupsulation) は、クラスの持つフィールドに対してクラス内部からアクセスする場合もアクセサメソッドを経由して行うパターンです。

以下のコード(Javaっぽい疑似コードです)は、自己カプセル化のパターンを適用する前のコードです。コンストラクタおよび getUserName で、アクセサメソッドを経由せずに firstNamelastName にアクセスしています。

class UserName {
  private String firstName;
  private String lastName;

  public UserName(String firstName, String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  public String getUserName() {
    return firstName + " " + lastName;
  }
}

firstNamelastName に対するアクセサメソッドを追加して、 firstNamelastName へのアクセスをアクセサメソッド経由に変更します。

class UserName {
  private String firstName;
  private String lastName;

  public UserName(String firstName, String lastName) {
    setFirstName(firstName);
    setLastName(lastName);
  }

  public String getUserName() {
    return getFirstName() + " " + getLastName();
  }

  private void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  private String getFirstName() {
    return firstName;
  }

  private void setLastName(String lastName) {
    this.lastName = lastName;
  }

  private String getLastName() {
    return lastName;
  }
}

これだけだとコード量が増えただけで旨味がないですが、例えばsetterにassertionを追加した場合はどうでしょうか。この場合、 firstName への代入を必ずsetter経由で行うのであれば、 firstNamenull を代入できないことが保証されます。

  private void setFirstName(String firstName) {
    assert firstName != null;
    this.firstName = firstName;
  }

また、例えば仮に「 firstName は10文字以上を設定しなければならない」という仕様が追加された場合であっても、容易にそれを保証することができます1

  private void setFirstName(String firstName) {
    assert firstName != null;
    assert firstName.length >= 10;
    this.firstName = firstName;
  }

クラスの内部からアクセサメソッド経由でフィールドにアクセスするメリットは他にもあって、例えば、クラスの継承を行う場合にサブクラスでのフックを提供できるということが挙げられます。

But there are common circumstances where self-encapsulation is worth the effort. If there is logic in the setter, then it’s wise to consider it for any internal updates too. Another circumstance is when the class is part of an inheritance structure, in which case the accessors provide valuable hook points for subclasses to override behavior. (Martin Fowler(2017))

Reference

  1. Martin Fowler、(2017)、SelfEncapsulation、Retrieved from https://martinfowler.com/bliki/SelfEncapsulation.html(最終アクセス日:2022/06/05)

  1. 「仮に」です。 ↩︎

#Design

About me 😎

profile

茨城県つくば市在住のソフトウェアエンジニアです。専門領域はAndroidアプリ開発で、特にアーキテクチャに興味があります。某社でAndroidアプリ開発のテックリードをしています。

Jetpack ComposeによるAndroid MVVMアーキテクチャ入門の著者です。

👉 もっと詳しく

Writing 📝

Android MVVMアーキテクチャ入門

Androidアプリ開発の初学者に向けた、MVVM(Model-View-ViewModel)アーキテクチャの入門書を書きました。初学者の方を確実にネクストレベルに引き上げる技術書です。

👉 もっと詳しく

See Also 👀