728x90
반응형

코딩을 하다보면 내가 짠 코드가 좋은 코드인지 나쁜 코드인지 궁금할 때가 있다. 물론 목적에 부합하는 결과가 항상 나오고 아무도 불편없이 사용하고 있다면 굳이 좋은 코드인지 나쁜 코드인지 궁금하지도 않겠지만, 현실에서 그런 일은 거의 일어나지 않는다. 사용자의 요구에 따라 여러가지 기능이 추가되기도 하고 삭제되기도 하며 그 과정에서 수많은 에러가 추가적으로 발생하기도 한다. 이러한 변경에 빠르게 대응할 수 있고, 에러가 적어 신뢰성이 높은 프로그램을 만들었을 때 일반적으로 우리는 그것을 좋은 코드라고 부른다.

객체지향언어는 좋은 코드를 작성하기 위한 4대 기본 원칙이 있다. 이 원칙들은 각각 무엇을 의미하는지, 그리고 왜 중요한지 예제를 통해 알아보자.

객체 지향 언어의 4대 기본 원칙 :

  • 캡슐화 (Encapsulation)
  • 추상화 (Abstraction)
  • 상속 (Inheritance)
  • 다형성 (Polymorphism)

캡슐화 (Encapsulation)

아래 예제들을 더 쉽게 이해하기 위해 Main 함수를 작성하는 사람이 사용자이고, 나머지 클래스의 작성자는 개발자인 '나'라고 상상해보자.

// 통장 계좌
public class Account 
{
    public int balance; // 잔액
}

// 사용자 영역
class Program 
{    
    static void Main(string[] args)
    {
        Account myAccount = new Account();
        myAccount.balance += 2000; // 2000원 입금
        myAccount.balance -= 1000; // 1000원 출금
        Console.WriteLine($"잔액은 {myAccount.balance}원입니다");
        // -> 잔액은 1000원입니다.
    }
}

위의 예제에서 나는 통장 계좌를 의미하는 Account라는 클래스를 만들어 사용자에게 제공하였다. 사용자는 내가 만든 Account 클래스를 이용해 통장을 새로 개설(myAccount)하여, 2000원을 입금하고 1000원을 출금했다. 잔액을 확인해보니 1000원이 남았다.

이 예제는 기능을 수행하는데 아무런 문제가 없다.
캡슐화는 기본적으로 관련된 속성과 행위를 별도의 클래스로 묶는 것을 말하는데 이 예제에서는 Account라는 클래스를 만들었을 뿐 속성과 행위를 묶어놓지 않고 사용자가 Main()함수에서 직접 사용하도록 모두 열어주었기 때문에 캡슐화가 잘 되어있지 않은 코드다.

문제점을 파악해보자.

  1. 사용자가 잔액에 직접 접근 가능하도록 하여 정보를 조작할 수 있도록 허용하고 있다.
  2. 잔액이 음수를 허용하고 있다.
// 통장 계좌
public class Account 
{
    private int balance; //접근 제한자를 private 으로 
                         //하여 외부에서 볼수 없도록 함.

    public void Deposit(int money)
    {
        if (money < 0)
        {
            Console.WriteLine("음수를 허용하지 않습니다.");
            return;
        }        
        balance += money;
    }

    public void Withdraw(int money)
    {
        if (money < 0)
        {
            Console.WriteLine("음수를 허용하지 않습니다.");
            return;
        }
        if (balance < money)
        {
            Console.WriteLine("잔액이 부족합니다.");
            return;
        }
        balance -= money;
    }

    public void ShowBalance()
    {
        Console.WriteLine($"잔액은 {balance}원입니다");
    }
}

// 사용자 영역
class Program 
{    
    static void Main(string[] args)
    {
        Account myAccount = new Account();
        myAccount.Deposit(2000);  // 2000원 입금
        myAccount.Withdraw(1000); // 1000원 출금
        myAccount.ShowBalance();
        // -> 잔액은 1000원입니다.
    }
}

두 번째 예제는 첫번째보다 캡슐화가 더 잘된 코드라고 볼 수 있다.

  1. 잔액에 대한 접근제한자를 private으로 변경해 사용자는 잔액에 직접 접근하지 못하게 하였고, DepositWithdraw함수를 이용해서만 접근 가능하도록 하였다. (정보 은닉화)
  2. DepositWithdraw 함수 안에서 음수를 허용하지 않고 잔액이 부족할 경우 출금도 불가하다. 이런 것을 유효성 검사라고 하는데, 유효성 검사를 Main 함수에 작성하지 않고 클래스 안에서 해결하고 있다는 점이 중요하다. (관련된 속성이나 행위를 묶는다)

다음 포스트: 추상화

728x90
반응형

+ Recent posts