공부/그 외

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

sudo 2022. 9. 11. 16:07

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

각각의 객체들의 역할이 무엇인지를 정의하여 객체들 간의 상호 작용을 통해 프로그램을 만드는 것

객체란?

클래스라는 틀(template)에서 생겨난 실체(Instance)

 

객체 지향 프로그래밍을 사용해야 하는 이유는?

실세계에 대한 쉬운 모델링

응용 소프트웨어를 하나의 절차로 모델링 하기는 어렵다. 대부분의 응용 소프트웨어 특성상 절차보다는 관련된 여려 객체들간의 상호작용으로 모델링하는 것이 더 쉽고 적합하다

생산성

상속과 다형성으로 이미 만들어진 클래스를 기반으로 재정의해서 사용할 수 있고, 캡슐화로 만든 클래스를 실체화 시킨 객체를 계속해서 만들어낼 수 있다

보안성

캡슐화로 구현된 클래스에서 특정 부분을 은닉할 수 있다

 

SOLID (객체 지향 설계 원칙)

1. 단일 책임 원칙(SRP, Single Responsibility Principle)

  • 하나의 클래스는 단 하나의 책임만을 가져야 한다
  • 책임 영역을 확실하게 해서 한 책임의 변경에서 다른 책임의 변경으로의 연쇄 작용에서 자유롭게 할 수 있음

메소드가 SRP를 지키지 못한 경우

class 강아지 {
    final static Boolean 수컷 = true;
    final static Boolean 암컷 = false;
    Boolean 성별;

    void 소변보다() {
        if (this.성별 == 수컷) {
            // 한쪽 다리를 들고 소변을 보다.
        } else {
            // 뒷다리 두 개를 굽혀 앉은 자세로 소변을 본다.
        }
    }   
}

위의 강아지 클래스 코드를 보면 소변보다() 메소드에서 수컷, 암컷 모두 구현하려고 해서 단일 책임 원칙을 위반하고 있는 것을 볼 수 있습니다.

 

abstract class 강아지 {
    abstract void 소변보다();
}

class 수컷강아지 extends 강아지 {
    void 소변보다() {
        // 한쪽 다리를 들고 소변을 본다.
    }
}

class 암컷강아지 extends 강아지 {
    void 소변보다() {
        // 뒷다리 두 개로 앉은 자세로 소변을 본다.
    }
}

 

2. 개방-폐쇄 원칙(OCP, Open/Closed Principle)

  • 소프트웨어 요소(ex. 클래스, 모듈, 함수)는 확장에는 용이하지만 변경에는 닫혀있어야 한다

 

위의 그림을 보면 운전자는 자동차가 수동 기어인지 자동 기어인지에 따라 호출해야하는 함수가 달라진다. 이렇게 어떤 변화가 있을 때 바로 운전자에게 영향이 오기 때문에 이러한 설계는 개방 폐쇄 원칙에 위배됩니다.

 

이렇게 상위 클래스 또는 인터페이스를 중간에 둠으로써 다양한 자동차가 생긴다고 해도 객체 지향 세계의 운전자는 운전 습관에 영향을 받지 않게 됩니다. 다양한 자동차가 생긴다고 하는 것은 자동차 입장에서는 자신의 확장에는 개방되어 있는 것이고, 운전자 입장에서는 주변의 변화에 폐쇄돼 있는 것입니다.

 

3. 리스코프 치환 원칙(LSP, Liskov, Substition Principle)

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

리스코프 치환 원칙 위배

  • 아버지 - 딸(계층도/조직도)

리프코프 치환 원칙 만족

  • 동물 - 펭귄 구조(분류도)

위의 예시에서는 할아버지 = 사촌형; 처럼 상위형 객체 참조 변수에 대입해 상위 클래스의 인스턴스 역할을 하는데 문제가 있다. 하지만 아래 예시에서는 동물 = 참새; 처럼 상위 클래스의 인스턴스 역할을 하는데 문제 없다.

 

4. 인터페이스 분리 원칙(ISP, Interface Segregation Principle)

  • 범용 인터페이스 하나를 만들기 보다 클라이언트의 역할에 맞게 여러개의 인터페이스로 구성하는 것이 좋다

1번의 단일 책임 원칙과 다소 상반되는 원칙일 수 있다. 다만 둘 중 하나만 만족할 수 있다면 단일 책임 원칙을 만족하는 것이 더 좋은 해결책이다

 

5. 의존 관계 역전 원칙(DIP, Dependency Inversion Principle)

  • 구체화된 클래스(자주 변경되는 클래스)에 의존하면 안된다

자동차가 타이어에 의존하면 어떻게 될까요? 자동차 타이어는 자주 바뀌게 되는 것 중 하나입니다. 이렇게 자주 바뀌는 것에 의존하면 자동차는 영향을 받게 되어 있습니다. 즉, 자동차 자신보다 더 자주 변하는 스노우타이어에 의존하기에 좋지 않음을 알 수 있습니다.

 

 

자동차가 구체적인 타이어가 아닌 추상화된 타이어 인터페이스에만 의존하게 함으로써 타이어가 변경되어도 자동차가 영향을 받지 않는다. 

 

즉, 추상화된 상위 클래스(타이어)를 두어, 자동차 클래스가 변하기 쉬운것의 변화(ex. 스노우 타이어 or 일반 타이어)에 영향을 받지 않도록 한다

 

객체 지향 프로그래밍 vs 절차 지향 프로그래밍

절차 지향 언어의 대표적인 예로는 C언어가 있다. 절차 지향 언어에서 절차(Procedure)는 프로시저 혹은 함수를 의미하고, 따라서 함수 호출을 통해 추상화와 재사용성을 얻어내는 것에 초점을 맞춘 프로그래밍 방식이다. 절차 지향 프로그래밍에서는 하나의 큰 기능을 처리하기 위해 작은 단위의 기능들로 나누어 처리하는 Top-Down 방식으로 설계된다

 

예를 들어, 도형을 그리는 기능을 절차 지향 프로그래밍과 객체 지향 프로그래밍으로 각각 구현한다고 가정해보자

 

절차 지향 프로그래밍 방식

  • void drawLine(Position, Color)
  • void drawCircle(Position, Color)
  • void drawRectangle(Position, Color)
  • 위의 정의된 함수에 인자를 전달해 원하는 도형 그리기 실행

객체 지향 프로그래밍 방식

  • Shape라는 부모 클래스 선언 -> Position, Color, Width 등 멤버 변수를 가지고, draw(), move()등의 멤버 함수가 있음
  • Line, Circle, Rectangle 같은 도형들을 자식 클래스로 상속
  • 자식 클래스에서 각각 draw 멤버 함수를 재정의
  객체 지향 언어 절차 지향 언어
장점 상속과 다형성을 이용한 재사용성 빠른 실행 속도
단점 절차 지향 언어보다 실행 속도가 느림 구성 요소가 유기적으로 연결되어 있어서 일부분이 문제가 생기면 전체를 수정해야 하는 유지 보수의 어려움

 

Reference

http://www.incodom.kr/%EC%A0%88%EC%B0%A8_%EC%A7%80%ED%96%A5

 

절차 지향 - 인코덤, 생물정보 전문위키

# 절차지향([[Procedural oriented]]) 프로그래밍 이란?

www.incodom.kr

https://devlog-wjdrbs96.tistory.com/380

 

[Java] 객체지향 설계 5원칙 - SOLID란 무엇일까?

객체지향 설계 5원칙 SOLID 객체 지향 설계의 정수라고 할 수 있는 5원칙이 집대성됐는데, 바로 SOLID 입니다. SRP(Single Responsibility Principle): 단일 책임 원칙 OCP(Open Closed Priciple): 개방 폐쇄 원칙..

devlog-wjdrbs96.tistory.com