OOP: 캡슐화

hwisaac·2023년 2월 25일
0

oop

목록 보기
4/5

객체지향 프로그래밍의 캡슐화는 데이터와 메서드를 하나의 단위로 묶어 외부에서 직접 접근하지 못하도록 보호하는 개념입니다.

이를 통해 객체의 내부 구현 정보를 숨기고, 객체 간의 결합도를 낮춤으로써 코드의 유지보수성과 재사용성을 향상시킬 수 있습니다.

예를 들어, 아래와 같은 코드가 있다고 가정해봅시다.

class Employee {
  public name: string;
  public id: number;
  public department: string;
  public salary: number;

  constructor(name: string, id: number, department: string, salary: number) {
    this.name = name;
    this.id = id;
    this.department = department;
    this.salary = salary;
  }

  public calculateTax(): number {
    return this.salary * 0.1;
  }
}

위 코드에서는 Employee 클래스의 데이터와 메서드가 모두 public으로 선언되어 외부에서 직접 접근이 가능합니다.

이는 객체의 내부 구현 정보가 외부에 노출되어 있어, 객체지향의 캡슐화 원칙에 어긋나는 코드입니다. 이 코드를 캡슐화하여 수정해보겠습니다.

class Employee {
  private name: string;
  private id: number;
  private department: string;
  private salary: number;

  constructor(name: string, id: number, department: string, salary: number) {
    this.name = name;
    this.id = id;
    this.department = department;
    this.salary = salary;
  }

  public getName(): string {
    return this.name;
  }

  public getId(): number {
    return this.id;
  }

  public getDepartment(): string {
    return this.department;
  }

  public getSalary(): number {
    return this.salary;
  }

  public calculateTax(): number {
    return this.salary * 0.1;
  }
}

위 코드에서는 Employee 클래스의 데이터를 private으로 선언하여, 외부에서 직접 접근할 수 없도록 보호했습니다.

이제 Employee 객체를 생성한 코드에서는 Employee 객체의 데이터에 직접 접근할 수 없으며, getName(), getId(), getDepartment(), getSalary()와 같은 메서드를 사용하여 간접적으로 데이터에 접근할 수 있습니다.

이렇게 객체의 데이터와 메서드를 하나의 단위로 묶어 외부에서 직접 접근하지 못하도록 보호하는 것이 객체지향의 캡슐화입니다.

캡슐화의 장점과 단점

캡슐화를 하면 좋은 점은 다음과 같습니다.

  1. 코드의 안정성을 높일 수 있습니다.

캡슐화를 통해 외부에서 객체의 상태를 직접 접근할 수 없기 때문에 객체의 내부 상태가 불변하게 유지됩니다. 이로 인해 예기치 않은 상태 변경을 방지할 수 있으며, 코드의 안정성을 높일 수 있습니다.

  1. 객체의 내부 구현을 숨길 수 있습니다.

캡슐화를 통해 객체의 내부 구현이 외부에 노출되지 않기 때문에 객체를 사용하는 다른 코드에 대한 의존성을 줄일 수 있습니다. 이로 인해 코드의 유지보수성을 높일 수 있습니다.

  1. 코드의 재사용성을 높일 수 있습니다.

캡슐화를 통해 객체의 내부 구현이 외부에 노출되지 않기 때문에 객체를 다른 코드에서도 쉽게 사용할 수 있습니다. 이로 인해 코드의 재사용성을 높일 수 있습니다.

반면에, 캡슐화를 하면 나쁜 점은 다음과 같습니다.

  1. 코드의 이해도가 떨어질 수 있습니다.

캡슐화를 지나치게 하면 객체의 내부 구현을 숨기기 때문에 객체의 내부 동작을 이해하는 데 어려움을 겪을 수 있습니다.

  1. 객체의 상태와 동작을 접근하기 위해 추가적인 인터페이스를 작성해야 할 수도 있습니다.

이로 인해 코드의 복잡도가 높아질 수 있습니다.

따라서, 객체지향 프로그래밍에서 적절한 캡슐화를 수행하는 것은 객체의 안정성과 유지보수성을 높일 수 있는 좋은 방법입니다.

그러나 캡슐화를 지나치게 하면 코드의 이해도가 떨어질 수 있으므로, 적절한 수준에서 캡슐화를 수행해야 합니다.

지나친 캡슐화

캡슐화를 하면서 발생하는 부작용 중 하나는 캡슐화를 지나치게 하면서 객체의 내부 구현이 외부에 완전히 감춰져서 객체의 동작에 대한 이해도가 떨어질 수 있다는 것입니다.

이로 인해 예상하지 못한 문제가 발생할 가능성이 높아집니다.

예를 들어, 다음과 같은 코드를 고려해보겠습니다.

class BankAccount {
  private balance: number = 0;

  public deposit(amount: number) {
    this.balance += amount;
  }

  public withdraw(amount: number) {
    if (amount <= this.balance) {
      this.balance -= amount;
    } else {
      console.log("Insufficient balance");
    }
  }

  public getBalance() {
    return this.balance;
  }
}

const account = new BankAccount();
account.deposit(1000);
account.withdraw(500);
console.log(account.getBalance()); // 500
account.balance = 1000000; // This should not be allowed!
console.log(account.getBalance()); // 1000000

위 코드에서 BankAccount 클래스는 계좌의 입출금과 잔액을 관리하는 객체입니다.

balance 필드는 클래스 외부에서 접근할 수 없도록 private으로 선언되어 있습니다.

그러나, 마지막 두 줄에서 account.balance를 직접적으로 접근하여 잔액을 변경할 수 있습니다.

이는 balance 필드가 완전히 캡슐화되어 있지 않다는 것을 보여줍니다.

이로 인해 예기치 않은 부작용이 발생할 가능성이 높아집니다.

이러한 문제를 해결하기 위해서는 balance 필드를 private으로 유지하면서도 외부에서 접근할 수 있는 메서드를 제공하는 것이 좋습니다.

이를 통해 BankAccount 클래스의 사용자는 balance 필드에 대한 직접적인 접근을 할 수 없게 됩니다

class BankAccount {
  private balance: number = 0;

  public deposit(amount: number) {
    this.balance += amount;
  }

  public withdraw(amount: number) {
    if (amount <= this.balance) {
      this.balance -= amount;
    } else {
      console.log("Insufficient balance");
    }
  }

  public getBalance() {
    return this.balance;
  }
}

const account = new BankAccount();
account.deposit(1000);
account.withdraw(500);
console.log(account.getBalance()); // 500
account.withdraw(1000000); // Insufficient balance
account.deposit(1000000);
console.log(account.getBalance()); // 1500000

위 코드에서 balance 필드는 여전히 private으로 유지되면서, deposit, withdraw, getBalance 메서드를 통해 외부에서 상태에 접근할 수 있게 됩니다.

이를 통해 캡슐화를 유지하면서도 객체의 동작에 대한 이해도를 높일 수 있으며, 객체의 안정성과 유지보수성을 높일 수 있습니다.

0개의 댓글