C# :: For Beginners

[C#] 객체 지향적 사고 다지기

Overview

지난 게시물 ([C#] 도대체 객체란 무엇인가?, [C#] 그렇다면 클래스는 무엇인가?) 에서 객체와 클래스의 개념에 대해 자세히 알아보았습니다. 이제 어느 정도 객체와 클래스의 개념을 이해하셨을 것으로 보여지는데요, 하지만 이러한 객체와 클래스를 이해하셨다고 해서 객체지향적인 프로그램을 설계하고 활용할 수 있는 것은 아닙니다. 이러한 개념은 꾸준히 연구하고 노력해서 나오는 것이기 때문입니다. 그래서 이번에는 클래스를 설계하는 방법을 다루어보려고 합니다. 이번 게시물의 대상은 앞서 설명드렸던 객체와 클래스의 개념을 이해하시고 계시며, 클래스의 문법 또한 어느 정도 이해하시고 계신 분들이 되겠습니다. 그럼 객체 지향 설계에 대해 알아보도록 하겠습니다.

객체지향의 단계적 활용

[ 업무 요청 ]

여러분은 어느 호텔의 고객 정보 프로그램을 유지하고 개발하는 개발자입니다.

어느 무료한 시간을 보내고 있던 와중 새로운 작업 요청이 들어왔습니다.

현재 호텔에 투숙하고 있는 고객들의 정보를 가지고 있다가 고객의 성별 (Gender) 데이터를 요청하면 해당 고객이 남성인지 여성인지 반환해주는 프로그램을 만들어주세요.

To. 고객관리 개발자

아주 간단한 프로그램 요청이 들어왔네요. 작업 내용을 한번 정리해보도록 하겠습니다. 호텔의 고객들의 성을 반환해주는 프로그램을 개발해 제공하면 됩니다. 그런데 잠시 저장시켰다고 요청한 고객의 성을 반환하는 프로그램이군요. 특별히 어려울 것이 없는 내용이긴 합니다. 위와 같은 업무를 받은 경우 여러분은 클래스를 어떻게 설계하고 정의해야될 지 생각해보시기 바압니다. 그리고 이제 단계별로 객체지향적인 설계를 해 보도록 할텐데요, 여러분이 생각하고 활용하는 객체지향의 능력은 어느 정도 되는지도 한번쯤 점검해보시기 바랍니다.

[ 객체 지향의 30% 활용 ]

public class Custom
{
    //여러 고객 정보들 생략.
    private bool Gender; // True = 남자, False = 여자
    public Custom(bool _Gender) // 고객의 성별을 저장하는 생성자
    {
        Gender = _Gender;
    }

    public string getGender
    {
        get {return Gender;}
        set {Gender=value;}
    }

    public string GetGender() // 고객의 성별을 반환하는 Method (메소드)
    {
        if (Gender)
            return "남자";
        else
            return "여자";
    }
}

객체를 30% 활용하여 작성된 코드를 살펴봅시다. 고객의 정도를 저장할 Custom 이라는 Class (클래스) 를 만들었습니다. 그리고 Gender (성별) 이라는 변수를 사용해서 고객의 성별이 남성인지 여성인지 구분하여 문자열을 전달합니다. 어떻습니까? 별 문제 없어보입니다. 대부분의 개발자 분들이 위와 같이 클래스를 설계할 것으로 사료됩니다.

하지만 위의 클래스 역시도 객체지향적인 설계로 보여지지 않습니다. 위의 프로그램 설계는 고객이 남성인지 여성인지 확인하기 위해서 생성한 객체인 Gender (성별) 이라는 변수를 확인 하여야 합니다. 다시 말해, 남성 고객, 여성 고객 두 가지의 객체로 만들어 놓게 되면 사실상 고객의 성별을 명확하게 구분할 수 없습니다. 이제 다음 단계에서 서 왜 효율적이지 못한 방법인지 알아보도록 합시다.

[ 객체 지향의 60% 활용 ]

public class Custom
{
    //여러 고객 정보들 생략.
}

public class Male : Custom
{
    public string GetGender()
    {
        return "남성";
    }
}

public class Female : Custom
{
    public string GetGender()
    {
        return "여성";
    }
}

이번에 설계한 클래스의 경우에는 고객 객체를 생성할 때 고객이 여자다 혹은 남자가 라는 인자를 기억해 둘 필요가 없습니다. 고객 클래스에서 Gender 인자를 제거해버렸습니다. 프로그램 메모리도 어느 정도 절약 할 수 있게 된 것이죠. 그리고 남성과 여성이라는 자식 클래스를 별도로 생성했습니다. 이 클래스는 고객의 성이 무엇이냐 라는 질문에 어떠한 플래그를 거치지 않고도 해당되는 고객의 성을 말할 수 있습니다. 여기서는 객체 지향의 상속성 (Inheritance) 이라는 개념을 도입한 것인데요, 너무나도 중요한 개념이므로 상속을 도입했다고 해서 첫 술에 배가 부르면 안돼겠지요? 이제 다형성 (Polymorphism) 과 추상화 (Abstraction) 의 개념을 도입하여 클래스를 설계해보도록 하겠습니다.

public abstract class Custom
{
    abstract public string GetGender(); // 추상화 (Abstract)
}

public class Male : Custom
{
    public override string GetGender() // 다형성 (Polymorphism)
    {
        return "남성";
    }
}

public class Female : Custom
{
    public override string GetGender()
    {
        return "여성";
    }
}

추상화 (Abstraction) 의 개념은 Custom 안의 GetGender() Method (메소드) 에서 사용되었습니다. 추상화라는 것은 표현하고자 하는 특성을 간추리는 작업을 의미합니다. Custom Class (클래스) 에서 추상적으로 선언된 GetGender Method (메소드) 는 Abstract 로 선언되어 있고, 각각의 Male, Female 클래스에서는 Custom 클래스를 상속 받고 그 안에서 GetString() 을 구체화 하여 사용합니다. 각각의 클래스에서 자신의 특성에 맞추어 구체화 되는 것을 다형성 (Polymorphism) 이라고 부릅니다. 같은 GetGender() Method (메소드) 이지만 남성과 여성의 두 가지의특성으로 사용되는 입니다. 위의 설계를 보면 추상화의 개념과 다형성의 개념이 잘 표현되고 있습니다.

[ 다형성과 추상화의 활용 ]

다형성과 추상화를 이용한 예시를 살펴보았습니다. 이제 객체에 대한 놀라움과 감탄이 나와야 할 타이밍인데요, 별다른 감흥이 오지 않으시는 분들이 대부분일 것입니다. 별 감동이 없으신 분들을 세 가지 경우로 나눌 수 있습니다.

첫 번째의 경우는 다형성과 추상화의 개념을 자주 도입해 사용하시고 있으신 분이라면 그다지 큰 감동을 느낄 수 없습니다. 괜한 시간낭비를 했다고 생각할 수 있습니다. -_-;

두번째는 다형성과 추상화의 개념을 파악하고 있었지만 필요성을 느끼지 못해서 적용해오지 않으셨던 분들입니다. 필자의 생각으로는 주로 두 번째 분류의 분들이 대부분일 것이라고 생각되어 집니다. 객체의 개념은 알고 있었지만 이제까지 별 다른 필요성을 느끼지 못해 왔다는 것입니다. 필자 역시 그래 왔었기 때문에 여러분의 마음을 이해할 수 있습니다. 그래서 특별히 후자에 해당되는 분들을 겨냥한 돌발 상황을 만들어 가정해보겠습니다.

여러분은 앞서 주문한 프로그램은 완성하였습니다. 하지만 추상화와 다형성의 개념은 별 필요성을 느끼지 못해 사용하지 않았습니다. 프로그램은 정상적으로 작동되었습니다. 하지만 여러분이 근무하는 호텔에는 외계인이 자주 방문해 묵습니다. 그런데 외계인은 자신이 중성이라며 자꾸 떼를 씁니다. 외계인의 끈질긴 요청에 의해 개발된 프로그램은 사용할 수 없었습니다. 호텔 경영진들은 남성과 여성 이외에 중성이라는 새로운 성별 요소를 추가하면 좋겠다는 간절한 소망을 가지고 있습니다.

이제 프로그램 수정! 이라는 새로운 업무가 나왔네요… ㅎㅎ 한 두번 있는 일도 아니지만, 너그럽게 수정 요청을 받아들이도록 합시다. 자, 이제 30%, 90% 의 설계를 살펴보면서 어떻게 수정하면 좋을지 생각해보도록 합시다.

일단, 30% 활용한 설계일 경우를 살펴봅시다. 클래스 자체가 상당히 복잡해질 것으로 예상됩니다. 플러그의 형태를 변화시켜주어야 하고, GetGender() 이라는 메소드를 수정하여야 합니다. 이러한 작업으로 인해 클래스는 간결하지 않고 계속해서 복잡해지게 됩니다.

그럼 객체 지향을 90% 활용한 클래스를 살펴보도록 합시다. 다형성의 개념을 가지고 있어 단지 중성 클래스를 확장함으로서, 간단히 문제를 해결할 수 있게 됩니다.

객체 지향적 사고는 한번 만에 이해하기 어려운 것이 특징입니다. 객체 지향적 사고를 가지기 위해서는 많이 설계해보고 토론해보고 또 생각해보는 노력이 필요합니다.

객체지향적 설계 방법

순차적으로 진행되어야 할 객체지향 설계 방법을 정리해보겠습니다.

1) 구현할 대상 (객체) 를 선별합니다.
→ 남성, 여성을 구분해냈던 과정처럼 연관성있는 객체들부터 분별해냅니다.

2) 중복되는 요인을 확인합니다.
→ 중복되는 부분들을 뽑아내어 하나의 부모 클래스로 묶는 작업을 의미합니다.

3) 상속 받은 후, 각자의 특징대로 클래스를 다시 정의합니다.
→ 고객 클래스를 상속받은 후 남성, 여성, 중성 과 같이 나누는 작업을 의미합니다.

객체 지향의 개념에 사실상 정답은 존재하지 않습니다. “이렇게 하는 것이 객체 지향적으로 설계하는 것이다.” 라는 것은 극히 주관적인 발언이 되는 것입니다. 하지만 효율적인 객체 지향적인 프로그래밍 설계를 하기 위해서는 객체들의 특성을 자유롭게 활용할 수 있도록 노력하는 작업이 필요합니다. 앞의 예제에서 적용해 본 객체의 속성은 추상화 (Abstraction), 상속성 (Inheritance), 다형성 (Polymorphism) 이었는데요, 이 밖에도 캡슐화 (Encapsulation), 주체성 (Identity), 분류성 (Classification) 등등의 다양한 개념들이 존재합니다.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s