객체 지향 프로그래밍, OOP is A PIE, SOLID

BK·2024년 4월 11일
0

Java

목록 보기
3/9

Java는 객체 지향 프로그래밍(OOP) 언어이다.

객체 지향 프로그래밍이라 하면 항상 따라 나오는 것들이 있다.

OOP is A PIE. 그리고 SOLID

위 두 단어 A PIE, SOLID에 대해 알아보고, 짧은 기간이지만 Java를 사용하며 느꼈던 "객체 지향"에 대해 짧게 써보고자 한다.

A PIE (캡상추다)

A PIE는 객체 지향의 4가지 특징을 앞 글자를 따서 만든것이다. 각각

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

를 의미한다. 한글로 하면 캡상추다

추상화(Abstraction)

피카소의 그림을 보면 이게 도데체 뭔가 싶지만 사람을 그린게 맞나 싶지만, 놀랍게도 우리는 이름 사람으로 인식할 수 있다. 이는 피카소가 사람이라는 존재를 추상화하여 그림에 나타냈기 때문일 것이다. 그렇다면 OOP에서의 추상화란 무엇일까

추상화란 객체들의 공통적인 본질을 뽑아내는 것이다.

추상화는 여러 객체들 중 공통적인 본질을 뽑아 구성하는 것이며, 왜 추상화를 하는가? 라는 질문에는 다양한 의견이 있을 수 있겠지만, 공통적인 부분을 추출하여 이를 재사용하기 위함이라 생각한다.

상속(Inheritance)

상속이란 자식이 무언가를 부모로부터 받는것이다.
OOP에서의 상속이란, 상위 클래스(super class)의 속성을 하위 클래스(sub class)에 전달하고, 하위 클래스에서 이를 사용할 수 있는 것이다. 위에서 언급한 추상화를 통해 추출한 공통된 본질을 상속을 통해 하위 클래스에 전달하여 재사용 가능하게 한다.

캡슐화(Encapsulation)

캡슐화는 객체의 속성을 외부로부터 숨기는 것이다.
Java에서의 캡슐화는 field들을 private으로 두고, getter, setter나 builder pattern 등을 활용하는 것 정도로 생각 할 수 있겠다.
하지만, 단순히 private한 field를 선언하는 것 뿐 아니라 interface와 같이, 그 내부 혹은 뒤에 있는 내용들을 숨기면서 사용 가능한 interface를 제공하는 것이 OOP의 캡슐화라고 생각한다.

다형성(Polymorphism)

다형성이란 프로그램 언어의 요소들이 다양한 자료형(타입)에 속하는 것이 허가되는 성질을 가르킨다. 즉,
“하나의 타입으로 여러 가지 객체를 사용할 수 있는 것” 또는 “하나의 객체가 여러 타입에 담길 수 있는 것” 정도로 요약할 수 있겠다.

Java에서 다형성을 구현하는 방법은 대표적으로 (type) up casting, method overriding, overloading 등이 있다.

SOLID

그럼 이건 뭐냐? A PIE가 객체 지향의 4가지 특징을 나타내는 말이라면, SOLID는 객체 지향 설계의 5가지 원칙을 나타낸다. 각각의 원칙은 다음과 같다.

  • SRP(Single Respnsibility Principle) : 단일 책임 원칙. 한 클래스는 하나의 책임만 가져야 한다.
  • OCP(Open Closed Principle) : 개방-폐쇄 원칙. 소프트웨어 요소는 확장에는 열려있으나 변경에는 닫혀 있어야 한다. (이게 무슨 소린가)
  • LSP(Liscov Substitution Principle) : 리스코프 치환 원칙. 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바뀔 수 있어야 한다.
  • ISP(Interface Segregation Principle) : 인터페이스 분리 원칙. 특정 클라이언트를 위한 interface 여러개가 범용 interface 하나보다 낫다.
  • DIP(Dependency Inversion Principle) : 의존 관계 역전 원칙. 프로그래머는 추상화에 의존해야지, 구체화에 의존하면 안된다.

이게 다 무슨 말인가 싶을 수 있다. 이번 포스트에서는 5가지 원칙을 간략히 언급하고, 예시 코드를 포함한 내용은 추후 각각 작성해 보겠다.

SRP(단일 책임 원칙)

단일 책임 원칙이란 클래스는 단 하나의 책임만 가져야 한다는 원칙이다.

하나의 책임이라는 말이 혼동 되는 경우가 있는 것 같다. 단일 책임 원칙은 클래스는 하나의 일만 해야하는 것이 아닌 하나의 책임만 가져야 함을 의미한다. 즉, Person 클래스는 뛰거나, 걷거나 하나의 만을 해야하는 것이 아닌, Person이라는 액터(Actor)에 대한 책임만 가져야 하는 것을 의미한다.

Actor는 시스템을 수행하는 역할을 하는 요소이다.

OCP(개방-폐쇄 원칙)

개방-폐쇄 원칙이란 소프트웨어 요소는 확장에는 열려있으나 변경에는 닫혀 있어야 한다는 원칙이다.

무슨 소리인가 싶을 수 있지만, "기능을 추가(확장)할 수 있어야 하는데, 기존 코드는 수정(변경)하지 않아야 한다." 정도로 말할 수 있을 것 같다.

LSP(리스코프 치환 원칙)

리스코프 치환 원칙이란 하위 타입(sub class)은 상위 타입(super class)를 대체할 수 있어야 한다는 원칙이다.

하위 클래스를 보통 자식 클래스, 상위 클래스를 부모 클래스라고도 지칭하곤 하는데, 같은 말이다.
리스코프 치환 원칙은 하위 타입은 상위 타입의 method, field 등을 상속받고 이를 구현하여 상위 타입을 대체할 수 있어야 함을 의미하는데, 단순히 method signature 등 동작 가능하게 code를 작성하는 것이 아니라 그 하위 타입의 동작 또한 프로그램의 정확성을 깨뜨리지 않아야 함을 의미한다.

"즉, 프로그램의 정확성을 깨뜨리지 않고, 하위 타입이 상위 타입을 대체할 수 있어야 한다."

ISP(인터페이스 분리 원칙)

인터페이스 분리 원칙이란 client는 그들이 사용하지 않는 interface에 의존하지 않아야 한다는 원칙이다.

간략하게 말하자면, interface는 각자 관심에 맞는 작은 interface들로 분리하고, client는 작은 interface들을 구현하도록 해야 한다는 것이다.

"특정 client를 위한 여러 interface가 하나의 범용 interface보다 낫다.

DIP(의존관계 역전 원칙)

의존관계 역전 원칙이란 프로그래머는 구체화 된 클래스에 의존하는 것이 아닌, 추상화 된 interface를 의존하도록 해야 한다는 원칙이다.

DIP는 프로그래밍을 함에 있어서, 구체화 된 class 보다 interface를 의존해야 한다는 원칙이다.

객체 지향은 '재사용'이다.

객체 지향의 4가지 특징(A PIE)과 5원칙(SOLID)에 대해 간략하게 알아보았다.
개인적으로 4가지 특징 모두 연관되어 있다고 생각한다. 재사용성을 위해 추상화를 하고, 이를 상속 받아 재사용하며, 이러한 객체들을 효과적으로 활용하기 위해 다형성을 구현하고 활용하며, 캡슐화 또한 정보 은닉만의 관점이 아닌 interface의 관점에서 볼 때 재사용성과 관련이 있다고 생각한다.
결국 객체 지향은 "재사용"이다.

객제 지향 설계는 '분리'이다.

5원칙(SOLID) 또한 서로 관련이 없지 않다. SRP(단일 책임)을 통해 수정 사항을 최소화 하여, OCP(개방 폐쇄)를 지킬 수 있다. ISP(인터페이스 분리)를 통해 LSP(리스코프 치환)를 지킬 수 있으며, 또한 DIP(의존 역전)를 통해 LSP를 달성할 수 있다.
SOLID는 객체 지향 설계의 원칙이다. 프로그래머가 어떤 방식으로 설계를 해야 하는지에 대한 원칙이며, 5원칙을 지키기 위한 근간은 분리이다. (그냥 개인적인 생각이다.)
인터페이스를 관심사에 맞게 작게 분리하고, 활용하면 5원칙을 지킬 수 있고, 잘 설계 된 구조(?)를 통해 객체 지향의 4가지 특징을 잘 활용하면 재사용성이 높은 프로그램을 개발할 수 있을 것이다.

"객체 지향의 목적은 재사용이며, 재사용 가능한 프로그램을 위한 설계의 근간은 분리이다.

0개의 댓글