🦍

JavaとJavaScriptで学ぶカプセル化とクロージャー

2022/11/19に公開約3,100字

カプセル化とは

カプセル化はオブジェクト指向を構成する概念のひとつ。

カプセル化によって、オブジェクトの情報(フィールドやメソッドなど)を隠蔽することで、オブジェクトへの直接アクセスを制限する。

https://medium-company.com/カプセル化/

定義だけでは、わかりずらいので、実際のソースコードを見ると、理解が早まると思います。

Java でのカプセル化

Java では、フィールドにprivateをつけることで、外部からのアクセスを制限することができる。

public class PrivateInfo {
    private int importantNumber = 20001212;

    public int getImportantNumber() {
        return this.importantNumber;
    }

    public void setImportantNumber(int importantNumber) {
        this.importantNumber = importantNumber;
    }
}

public class Main {
    public static void main(String[] args) {
        PrivateInfo privateInfo = new PrivateInfo();
        System.out.println(privateInfo.getImportantNumber());
        privateInfo.setImportantNumber(20201230);
        System.out.println(privateInfo.getImportantNumber());
    }
}

// コンソール
// 20001212
// 20201230

簡単に言うと、書き換えられたくない変数にprivateをつけ、getter/setter を用意することで、外部からのアクセスを制限することです。

もしカプセル化していなかったら、以下のようになっていたでしょう。

public class PrivateInfo {
    public int importantNumber = 20001212;
}

public class Main {
    public static void main(String[] args) {
        PrivateInfo privateInfo = new PrivateInfo();
        System.out.println(privateInfo.importantNumber);
        privateInfo.importantNumber = 20001299;
        System.out.println(privateInfo.importantNumber);
    }
}

// コンソール
// 20001212
// 20001299

このように、直接変数にアクセスすることで、書き換えられてしまいます。
システムの保守性を下げる原因になります。

JavaScript でのカプセル化

JavaScript では、ES2015 からclassが導入されました。(Angular 以外で使われていることを、あまり見たことありませんが、、、)
しかし、Java で言うところのprivateは、JavaScript 2022 年 現在、導入されていません。

どのようにカプセル化を実現するのかというと、クロージャーを使います。

const PrivateInfo = () => {
  let importantNumber = 20001212;
  return {
    getImportantNumber() {
      return importantNumber;
    },

    setImportantNumber(number) {
      importantNumber = number;
    },
  };
};

const privateInfo = PrivateInfo();
console.log(privateInfo.getImportantNumber());
privateInfo.setImportantNumber(20201230);
console.log(privateInfo.getImportantNumber());

// コンソール
// 20001212
// 20201230

関数の中に変数を閉じ込めて、外部からアクセスできないようにしています。
アクセスするには、getImportantNumbersetImportantNumberを使うことで、アクセスできます。

もしカプセル化していなかったら、以下のようになっていたでしょう。

let importantNumber = 20001212;
console.log(importantNumber);
importantNumber = 20001299;
console.log(importantNumber);

// コンソール
// 20001212
// 20001299

そもそもクロージャーとは

ここでは詳しく解説しませんが、私が調べた限り
クロージャー:特定の変数を特定の関数にしか使わせないためのもの
という説明がしっくりきました。

https://www.youtube.com/watch?v=OY6plmd5qPE

TypeScript でのカプセル化

JavaScript にはprivateがないといいましたが、実は TypeScript では、privateが使えます。

class PrivateInfo {
  private importantNumber = 20001212;

  getImportantNumber() {
    return this.importantNumber;
  }

  setImportantNumber(number: number) {
    this.importantNumber = number;
  }
}

const privateInfo = new PrivateInfo();
console.log(privateInfo.getImportantNumber());
privateInfo.setImportantNumber(20201230);
console.log(privateInfo.getImportantNumber());

// コンソール
// 20001212
// 20201230

まとめ

TypeScript 便利。

GitHubで編集を提案

Discussion

ログインするとコメントできます