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

JS·2022년 12월 13일
0

Tech Reference

목록 보기
1/13
post-thumbnail

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

객체지향 프로그래밍은 컴퓨터 프로그래밍 패러다임 중 하나로, 프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체로 만들고 그 객체들 간의 상호작용을 하는 로직을 구성하는 프로그래밍 방법이다

예를 들어, 우리가 플레이 하는 온라인 게임중 팔을 짐승의 팔로 만든다거나 등에 천사의 날개를 단다거나 장비를 탈부착 한다는 등의 행동은 전부 객체지향 프로그래밍으로 구현할 수 있다

장점

  • 코드의 재사용이 용이하다
    남이만든 클래스를 가져와서 사용할 수 있고, 상속을 통해 확장해서 사용할 수 있다

  • 유지보수가 쉽다
    절차지향 프로그래밍에서는 코드를 수정해야할 때 일일이 찾아 수정해야하는 반면 객체지향 프로그래밍에서는 수정해야 할 부분이 클래스 내부에 멤버 변수혹은 메소드로 존재하기 때문에 해당 부분만 수정하면 된다

  • 대형 프로젝트에 적합하다
    클래스 단위로 모듈화시켜서 개발할 수 있으므로 대형 프로젝트처럼 여러 명, 여러 회사에서 프로젝트를 개발할 때 업무를 분담하기 쉽다

단점

  • 처리 속도가 상대적으로 느리다

  • 객체가 많으면 용량이 커질 수 있다

  • 설계시 많은 시간과 노력이 필요하다

객체지향 프로그래밍의 4대 특징

추상화(Abstraction)

  • 클래스와 객체
    • 클래스 : 분류에 대한 개념, 즉 같은 특성을 지닌 여러 객체를 총칭하는 집합의 개념(예를들어 사람)
    • 객체 : 유일무이한 존재(예를들어 박지성)
  • 객체지향 프로그래밍에서는 '추상화'라는 단어를 여러 군데 붙일 수 있다
  • 여기서 말하는 추상화는 추상 클래스나 추상 클래스가 갖는 추상 메소드를 의미하기보단 클래스를 설계하는 것 자체를 의미한다
  • 즉, 공통되는 속성이나 기능을 묶어 이름을 붙이는 것이다. 예를 들어 A라는 메소드나 클래스는 추상화 된 것이다

캡슐화(Encapsulation)

  • 캡슐화의 목적 2가지
    • 코드를 재수정 없이 재활용하는 것
    • 접근 제어자를 통한 정보 은닉
  • 절차지향 프로그래밍에서도 라이브러리를 통해 변수와 함수를 재활용할 수는 있었지만, 코드의 수정이 일어났을 때 영향 범위를 예상하기 어려운 문제가 있다
  • 그러나 객체 지향 프로그래밍에서는 캡슐화를 통해 객체가 외부에 노출하지 않아야 할 정보 또는 기능을 접근제어자를 통해 적절히 제어 권한이 있는 객체에서만 접근하도록 할 수 있다. 코드의 수정이 일어났을 때 책임이 있는 객체만 수정하면 되기에 영향 범위를 예측하기가 수월하다

상속(Inheritance)

  • 절차지향 프로그래밍에서도 '라이브러리'를 통해서 남이 짜 놓은 소스코드를 가져와 사용할 수 있다
  • 하지만 나의 의도에 맞게 수정하게되면 다른 라이브러리가 되어 버전에 따라 동작하지 않을 수 있으며 불필요한 코드의 수정작업이 생긴다
  • 상속은 이러한 문제를 해결하기 위하여 생긴 개념이며 부모클래스의 속성과 기능을 그대로 이어받아 사용할 수 있게하고 기능의 일부분을 변경해야 할 경우 상속받은 자식클래스에서 해당 기능만 다시 수정(정의)하여 사용할 수 있게 하는 것이다
  • 다중 상속은 불가하다. 클래스의 상속 관계에서 혼란을 줄 수 있기 때문에 상속은 반드시 하나만 가능하고 필요에 따라 인터페이스를 사용할 수 있게 했다

다형성(Polymorphism)

  • 하나의 변수명, 함수명 등이 상황에 따라 다른 의미로 해석될 수 있는 것
  • 오버라이딩(Overriding)과 오버로딩(Overloading)이 가능하다는 의미
    • 오버라이딩은 부모클래스의 메소드와 같은 이름, 매개변수를 재정의 하는 것이다
    • 오버로딩은 같은 이름의 함수를 여러개 정의하고, 매개변수의 타입과 개수를 다르게하여 매개변수에 따라 다르게 호출할 수 있게 하는 것이다

객체지향 프로그래밍의 5대 설계원칙 SOLID

객체지향의 장점은 많지만 결코 유지보수가 쉽지 않으며 코드가 혼란스러운것을 예방할 수는 없다

Robert C. Martin이 개발한 이 다섯 가지 지침과 원칙을 통해 개발자는 읽기 쉽고 유지 보수가 쉬운 프로그램을 만들 수 있다

S : Single Responsibility Principle 단일책임원칙

  • 단일 클래스는 오직 하나의 일을 가져야 한다

    • 만약 하나의 클래스가 하나 이상의 책임이 있다면, 다른 코드에 영향을 미칠 수 있다
    • 하나의 책임에 대한 변경은 다른 책임의 수정을 발생시킨다
    • 책임이란 말이 추상적으로 들린다면, 기능이라는 말로 생각하여도 좋다
  • 이 원칙의 적용은 클래스에만 국한되지 않으며, 소프트웨어 컴포넌트와 마이크로 서비스에도 적용된다

  • 클래스들이 같은 이유로 매번 변화하는 변화경향이 있다면, 클래스를 설계할 때 연관된 기능들을 함께 모으는 것을 목표로 해야한다. 우리는 기능을 분리하도록 노력하고, 기능들은 서로 다른 이유로 변경되어야 한다 -Steve Fenton

O : Open-Closed Principle 열린-닫힌 원칙

  • 소프트웨어 엔티티(클래스, 모듈 함수)는 확장을 위해 열려있고, 수정되서는 안된다

  • 수정과 확장은 별개이다. 우리는 구분할 필요성이 있다. 즉, 기존의 코드를 변경하지 않고 기능을 수정하거나 추가할 수 있도록 설계되어야 한다

  • 이 원칙이 재대로 지켜지지 않는다면 객체지향 프로그래밍의 장점인 유연성, 재사용성, 유지보수성 등을 모두 잃어버리는 것과 같다

L : Liskov Substitution Principle 리스코프 치환 원칙

  • 프로그램의 객체는 프로그램의 정확성을 꺠뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다

  • 즉, 상위 타입 객체를 하위 타입 객체로 치환해도 정상적으로 동작해야 한다는 말과 같다

  • 상속관계에서는 꼭 일관성 있는 관계인지 체크해야한다

  • 상속관계가 아닌 클래스들을 상속관계로 설정하면, 이 원칙이 위배된다

I : Interface Segregation Principle 인터페이스 분리 원칙

  • 한 클래스는 자신이 사용하지 않는 인터페이스는 구현하지 않아야 한다

    • 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다
  • 인터페이스는 클라이언트를 기준으로 잘게 분리되어야 한다. 멀티 프로세스의 독립된 구조들 처럼 서로 문제가 생기지 않게 분리시켜놓는 것이 핵심이다

D : Dependency Inversion Principle 의존성 역전 원칙

  • 프로그래머는 추상화에 의존해야지, 구체화에 의존해서는 안된다. 의존성 주입은 이 원칙을 따르는 방법 중 하나다

  • 즉 고수준 모듈(클래스)은 저수준 모듈(클래스)에 의존하지 말아야 한다는 의미이다

    • 고수준 클래스가 저수준 클래스를 사용하므로 고수준 클래스가 저수준 클래스에 의존하는 것이 자연스러워 보이지만, 저수준 클래스는 빈번하게 변경되고 추가될 때마다 고수준 클래스가 영향을 받기 쉬우므로 의존관계를 역전시켜야 한다

고수준 모듈 : 의미 있는 기능을 제공하는 모듈
저수준 모듈 : 고수준의 모듈을 제공하기 위해 필요한 모듈

SOLID 원칙은 서로 상호보완적이다

SRP와 ISP는 객체의 크기가 커지지 않도록 한다. 한 곳에서의 변경이 다른곳에 미치는 영향을 최소화 한다
LSP와 DIP는 OCP를 지원한다. 추상화와 다형성을 이용해 기능을 확장하면서도 기존 코드의 수정을 최소화한다

Reference

profile
게임 프로그래머 지망생

0개의 댓글