My Dream Being Visualized

객체지향 프로그래밍(OOP)이란? 본문

Backend/Design Pattern

객체지향 프로그래밍(OOP)이란?

마틴킴 2021. 12. 7. 21:21
728x90

 개인 공부를 위한 공간입니다. 틀린 부분 지적해주시면 감사하겠습니다 (_ _)

 

다들 많이 들어보았을 것이다.

나 또한 처음 배웠던 언어가 Python, 객체지향 프로그래밍 언어였다.

하지만 그 개념과 이점을 알지 못 했고,

결국 함수만 내리 만들다가 javascript의 세계로, typescript의 세계로 빠지는 중이다.

 

최근에 과제를 볼 기회가 생겼었는데,

FP와 OOP에 대해서 공부를 할 기회가 생겼고 새로운 세계를 접해버린 것 같다.

공부할 게 많지만, 즐겁다

 

아직 정확하게 알지 못 하기에, 조금씩 추가하면서 정리하려고 한다.

 

객체지향 프로그래밍이란?

함수와 로직보다는 데이터 혹은 오브젝트와 관련하여 소프트웨어 디자인(설계)를 구조화하는 컴퓨터 프로그래밍 모델이다. 

함수 생성 및 로직 작성보다는 데이터 및 오브젝트 관리를 위한 구조 설계에 초점을 맞춘 형태의 언어이다!

여전히 알아듣고 이해하기가 어렵다.
단번에 보고 이해되지 않았던 이유는, 내가 코드를 OOP의 장점을 살려 짜보지 않았기 때문이었던 것 같다.
몇개의 글과 코드를 분석한 후 OOP란 무엇일까, FP와의 차이점이 무엇일까에 대한 개념들을 이해할 수 있었고 어떤 분의 블로그 글에서 본 그림이 한눈에 이해하기가 쉬워 출처를 남기고 가져와 보았다.

출처:  https://seunghunchan.tistory.com/23  [Huna's Devlog]

출처: https://slidle.com/jivko/functional-programming/fp-vs-oop-diagram

OOP에는 특징이 4가지가 있다.

1) Encapsulation (캡슐화: 데이터(state)와 동작(function)을 하나의 객체 안에 묶어서 관리)
--> 각 클래스가 데이터와 동작을 독립적으로 가지고 있음
2) Abstraction (추상화: 모든 복잡함이 하나의 객체 안에 추상화되어, 유저는 단순한 instantiating 만으로 모든 프로퍼티들이 세팅된 객체를 생성)
--> Encapsulate된 각 클래스를 유저는 클래스의 인스턴스를 할당받아 간단하게 객체를 생성할 수 있음
3) Inheritance (상속화: 다른 클래스를 상속받음으로써 코드가 DRY(Don't repeat yourself, 코드반복X), 메모리 공간 절약)
--> 클래스가 클래스를 extends함으로써 (상속) 코드를 중복해서 쓸 필요가 없다. 객체지향에서 가장 중요한 개념이라고 함
4) Polymorphism (다형성: 같은 메소드를 다른 객체에서 사용할 수 있으며, 사용하는 객체에 따라 다른 결과물 출력)
--> 다른 클래스에서 선언한 메소드를 다른 클래스에서 사용할 수 있으며, state에 따라 다른 결과물을 출력

참고: https://soldonii.tistory.com/79?category=862198
마 이게 도대체 무슨 말이고!
코드를 보면서.... 이해해보자.
/*
	타입스크립트 기반
	설명: 내가 좋아하는 프로틴쉐이크를 주제로 작성하였다.
    	    프로틴쉐이크에는 브랜드가 2개가 있다고 가정했다. 
            셀렉스와 칼로바이
*/

/*
캡슐화: ProteinShake 클래스에서 각각의 데이터(name, grams)와 동작(drink)를 묶어서 관리!
*/
class ProteinShake {
    name: string;
    grams: number;
    // constructor는 생성자라고 하며, 객체 생성 시에 호출이 된다.
    constructor(name: string, grams: number) {
    // this는 해당 클래스 내에서 활용하겠다라는 의미이다.
    this.name = name;
    this.grams = grams;
    }
    drink() {
        console.log(`${this.name}에는 ${this.grams}이나 들었네!`);
    }
}

/*
상속화: 다른 클래스를 상속받음
*/
class Selex extends ProteinShake {
    flavor: string;
    constructor(name: string, grams: number, flavor: string) {
    // 상위 ProteinShake 클래스를 상속받음
        super(name, grams);
        this.flavor = flavor;
    }
    release() {
        console.log(`${this.name}에서 ${this.flavor}이 출시되었어요!`);
    }
}

class Calobye extends ProteinShake {
    supporter: string;
    constructor(name: string, grams: number, supporter: string) {
        super(name, grams);
        this.supporter = supporter;
    }
    supporters() {
        console.log(`${this.supporter}이 홍보하는 ${this.name}! 한번 드셔보세요!`);
    }
}

/*
추상화: instantiating(new Selex(...)) 만으로 모든 프로퍼티들이 세팅된 객체를 생성!
*/
const selex = new Selex('셀렉스', 20, '복숭아맛');
selex.drink(); // '셀렉스에는 20g이나 들었네!'
selex.release(); // '셀렉스에서 복숭아맛이 출시되었어요!'
const calobye = new Calobye('칼로바이', 25, '김계란');
/*
다형성: 같은 메소드를 다른 객체(selex.drink(), calobye.drink())에서 사용할 수 있으며, 사용하는 객체에 따라 다른 결과물 출력!
*/
calobye.drink(); // '칼로바이에는 25g이나 들었네!'
calobye.supporters(); // '김계란이 홍보하는 칼로바이! 한번 드셔보세요!
이제야 객체지향 프로그래밍 언어의 특징을 알게 된 것 같다.
이제는 그 장점을 살려 여러가지 패턴에 대해서 정리해볼 생각이다.
다 정리했을 때 쯤에는 정말로 발전된 개발자가 되어 있기를!