본문 바로가기
Development

[21.02.20] OOP - public, private and protected

by igy95 2024. 1. 8.

Reference

Private and protected properties and methods

OOP 의 중요한 관점 중 하나는 외부 인터페이스와 내부 인터페이스를 분리하고 그 접근성에 제한을 두는 것에 있다.

A real-life example

커피 머신을 예로 들어 보자. 이 커피 머신 외부에는 사용자와 접촉이 가능한 여러 인터페이스가 존재할 것이다. 이것은 버튼일 수도 있고, 화면일 수도 있다. 사용자는 최종 결과물인 커피를 얻기 위해 몇 가지의 인터페이스만 조작하면 되지만, 커피 머신 자체의 관점에서 하나의 커피를 만들기 위해서는 단순히 버튼을 누르는 행위만으로는 충분치 않을 것이다. 버튼을 누르는 행위를 기점으로 내부에 유기적으로 연결되어 있는 수많은 인터페이스들이 상호 작용할 것이고, 그 복잡한 과정을 거쳐야만 사용자가 예상하는 결과물을 만들어낼 수 있다.

 

하지만 사용자가 굳이 이런 것까지 알아야 할까? 아니, 사용자는 그냥 몇 번의 조작으로 좋은 커피를 얻을 수 있기만 하면 된다. 더군다나 이렇게 내부에 있어야할 인터페이스들이 쉽게 노출된다면 사용자에게 남는 건 복잡성과 위험성의 증가일 뿐이다. 결국 이러한 예시가 OOP 측면에서 보았을 때, 인터페이스 분리의 필요성을 야기하는 것이고 우리는 그에 대한 대답으로 이 글의 주제인 3가지 종류의 필드를 예시로 들 수 있다.

Internal and external interface

OOP 에서, 프로퍼티와 메소드는 두 그룹으로 분리될 수 있다.

 

  • 내부 인터페이스: 클래스 내부의 다른 메소드로부터 접근이 가능하지만, 외부에서는 허용되지 않는다.
  • 외부 인터페이스: 외부에서 접근이 가능하다.

내부의 인터페이스는 위치하고 있는 객체를 작동시키는 데 사용된다. 세부적인 것들은 서로를 작동시키는 데 사용될 뿐, 외부의 접근에는 완벽히 차단된다. 외부에서 사용할 수 있는 것은 오직 외부 인터페이스일 뿐이고, 이렇게 분리되어 있는 채로 객체의 정상적인 작동을 가능케 하는 것이 안정성을 보장한다.

 

JS에서는, 두 종류의 객체 필드(프로퍼티, 메소드)가 있다.

 

  • Public : 어디서든 접근이 가능하고, 외부 인터페이스를 구성한다.
  • Private(#) : 클래스 내부에서만 접근이 가능하고, 내부 인터페이스를 구성한다.

그 밖에 기능적인 부분을 지원하지는 않지만, 널리 알려진 컨벤션으로 사용되는 Protected(_) 필드가 있다. 이 필드는 public과 private의 중간 성격을 띄고 있는데, 이 특징은 다른 언어를 모방하여 내부 클래스 + 상속 클래스까지 접근이 가능하도록 '약속' 되어 있다.

Getter & Setter

기존의 getter & setter 정리(notion)

요즈음 getter & setter 함수는 get.../set... 으로 많이 사용된다. 이름 자체는 좀 더 길 수 있지만 다수의 인자를 받을 수 있어 더 유연하게 사용할 수 있기 때문이다. 하지만 기존의 get/set 도 간결성을 제공하기 때문에 이 부분은 개발자의 취향 차이다.

Private field

private 필드는 #(해시)를 prefix로 사용한다. 이것을 붙인 변수나 메소드는 외부에서 접근이 불가하지만, 해당 필드가 포함된 메소드를 외부에서 사용하는 것은 지장이 없다.

class Test {
    #privated = true;

    #fixPrivated() {
        this.#privated = false;
    }

    setPrivated() {
        this.#fixPrivated();
    }
}

let test = new Test();
test.#privated; // Error
test.#fixPrivated(); // Error
test.setPrivated(); // Success

Summary

OOP 관점에서, 이러한 인터페이스의 분리를 '캡슐화'라고 한다.