Java for Web[2] - Java와 객체지향

신동원·2022년 2월 21일
0

Java for Web

목록 보기
2/6

Java 언어의 특징

  1. Virtual Machine 사용 - 운영체제의 영향을 받지 않는다. OS 위에서 돌아가는 것이 아니라 OS 위의 VM에서 돌아감(VM은 각 운영체제별로 다름. 한 번 짠 코드는 각 VM에서 똑같이 돌아감)
  2. Garbage Collection - 메모리 관리
  3. Object Oriented Programming - 객체지향언어

객체지향 언어의 특징과 장점

객체지향 언어의 특징:

  1. 캠슐화: 데이터와 알고리즘을 하나로 묶어 외부에서 알 수 없는 하나의 캡슐로 만드는 것
  2. 상속: 상위 클래스의 모든 것을 하위 클래스가 이어받는 것
  3. 다형성: 하나의 객체가 다른 여러 객체로 재구성되는 것
  4. 추상화: 공통적인 부분을 파악해 추출하고 필요없는 것을 제거하는 것

객체지향 언어의 장점

  1. 재사용성: 상속이 가능하기 때문에 코드 재사용
  2. 생산성: 유지보수에 용이
  3. 자연스러운 모델링: 객체지향언어 자체가 우리가 사는 세상을 닮아서?

객체지향의 5원칙(SOLID)

출처: https://jaeyeong951.medium.com/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-5%EC%9B%90%EC%B9%99-solid-ac7d4d660f4d

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

THERE SHOULD NEVER BE MORE THAN ONE REASON FOR A CLASS TO CHANGE.
SOLID의 S에 해당하는 원칙으로 모든 클래스는 각각 하나의 기능만 가진다는 의미입니다. 다시 말하면 해당 클래스가 제공하는 모든 서비스는 단 하나의 책임을 수행하는 데 집중되어야 한다는 원칙입니다.
SRP 원칙을 적용하면 다른 클래스들이 서로 영향을 미치는 연쇄작용을 줄일 수 있습니다. 응집도(cohesion)는 높이고 결합도(coupling)은 낮출 수 있죠. 뿐만 아니라 책임을 적절하게 분배함으로써 코드의 가독성 향상, 유지보수 용이라는 이점까지 누릴 수 있으며 다른 원칙들을 적용하는 기초가 됩니다. 사뭇 단순한 원칙이라고 생각될 수 있으나, 막상 실무에 적용하려 하면 프로젝트의 복잡하고 빈번하게 변하는 성격때문에 적용하기가 쉽지 않습니다.

2. 개방폐쇄의 원칙 : OCP (Open Close Principle)

YOU SHOULD BE ABLE TO EXTEND A CLASSES BEHAVIOR, WITHOUT MODIFYING IT.
SOLID의 O에 해당하는 원칙으로 소프트웨어의 모든 구성요소(클래스, 모듈, 함수)는 확장에는 열려있고, 변경에는 닫혀있어야한다는 원칙입니다. 다시 말하면 요구사항의 변경이나 추가사항의 발생하더라도, 기존 구성요소는 수정이 일어나지 말아야하며 쉽게 확장이 가능하여 재사용할 수 있어야 한다는 뜻입니다. 로버트 마틴은 OCP는 관리가 용이하고 재사용 가능한 코드를 만드는 기반이며, OCP를 가능케 하는 중요한 메커니즘은 추상화(Abstraction)와 다형성(Polymorphism)이라고 설명합니다. OCP는 객체지향의 장점을 극대화하는 아주 중요한 원리입니다.
클래스를 설계할 때 변할 부분과 변하지 않을 부분을 명확히 구분해야 겠습니다.
변할 수 있는 부분은 추상화하여 상속하는 클래스가 의존할 수 있게 코드를 작성합니다.
적당한 추상화 레벨을 선택해야 합니다. 그래디 부치에 의하면 추상화란 ‘다른 모든 종류의 객체로부터 식별될 수 있는 객체의 본질적인 특징’ 이라고 정의합니다. 이 ‘본질적인 특징’을 명확히 정의할 수 있어야겠습니다.
Interface란 이런 변하지않을 본질적인 특징에 관한 약속입니다. Interface의 한 예시로 게임 캐릭터들의 스킬이 있습니다. 캐릭터가 스킬을 습득해서 스킬 버튼이 활성화 되었을 경우 스킬이 어떤 내용인지는 모르더라도 버튼을 누를경우 캐릭터가 어떤 행동을 할것이라는 사실은 자명합니다. 뭐 빙글뱅글 돌수도있고 점프를 할 수도 있겠죠. 스킬의 자세한 내용은 레벨업을 하거나 전직을 하거나 하면서 달라질 수 있지만 버튼을 누르면 스킬이 나간다는 사실은 변하지 않습니다.
위 예가 변하는 부분과 변하지 않는 부분이 잘 나뉘어있는 즉 interface의 좋은예라고 생각합니다.

3. 리스코브 치환의 원칙 : LSP (the Liskov Substitution Principle)

FUNCTIONS THAT USE POINTERS OR REFERENCES TO BASE CLASSES MUST BE ABLE TO USE OBJECTS OF DERIVED CLASSES WITHOUT KNOWING IT.
SOLID의 L에 해당하는 원칙으로 부모 클래스를 카리키는 포인터에 해당 클래스를 상속하는 자식 클래스를 할당하더라도 모든 기능이 정상적으로 작동해야 하며 자식 클래스의 상세 내부를 부모 클래스는 알 필요가 없다는 뜻입니다. MIT 컴퓨터 공학 교수인 리스코브가 제안한 설계 원칙으로 서브 클래스가 확장에 대한 인터페이스를 준수해야 함을 의미합니다.
한마디로 부모 클래스를 상속한 자식 클래스는 부모 클래스의 역할을 정확히 해내야한다는 뜻입니다.
정말 당연한 말이지만 좀 처럼 지켜지지 않는 원칙입니다.
보통 부모 클래스의 메소드를 override하면서 문제가 발생합니다. 부모 클래스의 기존 메소드를 자식 클래스가 수정하면서 문제가 생기는 것이죠.
LSP를 지키는 가장 간단한 방법은 상속을 하되 override를 안하는 것입니다. 하지만 이게 무조건 적인 방법은 아닙니다.
상속을 할 때 override가 필요하다면 기존 부모 클래스의 메소드가 하던 역할을 충실히 수행하고 기능의 추가만 신중하게 수행하면 됩니다.
LSP는 결국 상속의 과정 중 메소드의 재정의가 필요하다면 현재 자식 클래스가 부모 클래스의 기존 메소드의 의미를 해치지는 않는지 신중히 고민하고 올바르게 상속하라는 의미라고 생각합니다.

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

CLIENTS SHOULD NOT BE FORCED TO DEPEND UPON INTERFACES THAT THEY DO NOT USE.
SOLID의 I에 해당하는 원칙으로 자신이 사용하지 않는 인터페이스는 구현하지 말아야 한다는 원칙입니다. 다시 말하면, 하나의 큰 인터페이스를 상속 받기 보다는 인터페이스를 구체적이고 작은 단위들로 분리시켜 꼭 필요한 인터페이스만 상속하자는 의미입니다. SRP가 클래스의 단일책임을 강조했다면 ISP는 인터페이스의 단일책임을 강조합니다.
인터페이스 하나의 크기가 크다는 것은 한번에 지켜야할 약속이 많아진다는 것을 의미합니다.

5. 의존성 역전의 원칙 : DIP (Dependency Inversion Principle)

A. HIGH LEVEL MODULES SHOULD NOT DEPEND UPON LOW LEVEL MODULES. BOTH SHOULD DEPEND UPON ABSTRACTIONS.
B. ABSTRACTIONS SHOULD NOT DEPEND UPON DETAILS. DETAILS SHOULD DEPEND UPON ABSTRACTIONS
SOLID의 마지막인 D에 해당하는 원칙입니다. 위 원문을 그대로 번역하면 ‘상위 모듈은 하위 모듈에 의존해서는 안된다. 둘 다 추상화에 의존해야한다.’, ‘추상화는 구체적인 것에 의존해서는 안된다. 구체적인 것은 추상화에 의존해야한다.’ 입니다. 글만 읽었을 때는 무슨 뜻인지 쉽게 와닿지 않습니다.
클래스 사이에는 의존관계가 존재하기 마련입니다. 다만 의존 관계가 존재하되, 구체적인 클래스에 의존하지 말고 최대한 추상화한 클래스에 의존하라는 뜻입니다. 다시말하면 interface를 적극적으로 활용하라는 의미이기도 합니다.

profile
리액트를 좋아하는 프론트엔드 개발자

0개의 댓글