좋은 객체 지향이란?

Kyuwon Cho·2022년 4월 29일
0

Spring

목록 보기
2/5

객체 지향 프로그래밍

자바를 배우면서 객체 지향 프로그래밍은 객체간의 상호작용을 통해 프로그램을 만드는 것을 배웠다.

그냥 클래스를 통해 객체를 만들어 프로그래밍하는 것이 올바른 객체 지향 프로그래밍이라 할 수 없다. 그렇다면 좋은 객체 지향이란 뭘까?

객체 지향 특징

객체 지향 프로그래밍에는 4가지 특징이 있다.
1. 추상화
실생활에서 객체를 추상화 하여 클래스로 구현
2. 캡슐화
외부의 접근을 막아 데이터 변경을 제한, 함수 호출을 통해 데이터 변경(기능)
3. 상속
클래스나 인터페이스를 상속받아, 추가, 변경하여 사용 가능.
4. 다형성
하나의 객체가 여러가지 타입을 가질 수 있는 것. 프로그램을 유연하고 변경이 용이하게 만들 수 있다. 주로 대규모 소프트웨어 개발에 많이 사용.

객체 지향 프로그램

  • 유연하고 변경이 용이한 구조
    • 컴포넌트 유연하게 변경 및 개발
  • 특징 중 다형성이 중요

다형성

  • 역할 + 구현
    • ex) 자동차을 운전할 줄 알면(역할), 모델은 큰 상관이 없이 운전 할 수 있다.
      • 운전 = 역할
      • 모델 = 구현
    • ex2) 뮤지컬에서 같은 배역에 여러 배우를 쓸 수 있다
      • 배역 = 역할
      • 배우 = 구현
    • PC 하드웨어도 기능은 같지만 모델이 여러개일 수 있다
      • CPU = 역할
      • amd cpu(모델이 어떻든) or Intel CPU = 구현
  • 역할과 구현으로 구분 -> 단순 + 유연
  • 클라이언트는 역할만 알아도 사용이 가능
    • 역할만 유지하면 서버를 수정해도 영향을 받지 않는다

자바 다형성

  • 객체 지향의 핵심
  • 역할 = 인터페이스
  • 구현 = 인터페이스 구현 클래스 or 객체
    객체 설계시 역할과 구현의 명확한 분리 필요
  • 인터페이스 먼저 설계 후, 구현

좋은 객체 지향 5가지 원칙 (SOLID)

1. SRP (Single Responsibility Principle)

  • 단일 책임 원칙
  • 한 클래스는 하나의 책임만 가진다
    • 하나의 책임이란 기준이 모호
      • 규모의 차이
      • 문맥의 차이
  • 기준 : 변경이 불러오는 파급 효과
    • 변경시 파급 효과가 적으면 단일 책임 원칙을 잘 따른 것

2. OCP (Open/Closed Principle)

  • 개방-폐쇄 원칙
  • 확장은 열고 변경은 닫는다
    • 확장을 하려면 기존 코드를 변경하는데 무슨 개소리? (DIP 참조)
      • 다형성을 활용해서 인터페이스로 새로운 클래스로 새로운 기능 구현
      • 그래도 수정은 필요하므로 연관 관계를 맺어주는 조립, 설정자 필요

3. LSP (Liskov Substitution Principle)

  • 리스코프 치환 법칙
  • 컴파일의 성공여부를 떠나서 인터페이스의 규약은 하위 클래스들은 무조건 지켜줘야 한다. 컴파일 가능 여부가 중요하기보다 신뢰성이 중요! = 프로그램의 정확성
    • 더하는 기능은 무조건 더해야됨 -> 빼기 곱하기 안됨

4. ISP (Interface Segregation Principle)

  • 인터페이스 분리 원칙
  • 범용적으로 사용되는 인터페이스보다 특정 역할을 맞는 다수의 인터페이스가 더 좋다.
    • ex) 자동차라는 인터페이스, 클라이언트를 운전, 정비 인터페이스, 클라이언트로 분리하기
      • 정비 인터페이스 변경 -> 운전 클라이언트 영향 X
      • 인터페이스 명확 -> 대체 가능성 Up

5. DIP (Dependency Inversion Principle)

  • 의존 관계 역전 원칙
  • 추상화에 의존, 구체화 의존 X
    • = 구현 클래스보다 인터페이스에 의존
  • 역할에 의존하기 -> 클라이언트가 인터페이스에 의존해야 구현을 유연하게 할 수 있다.
  • OCP에서 기존 코드를 변경했던 것은 서비스가 인터페이스를 의존하지만 동시에 구현 클래스도 의존하기 때문 (김연한 강의 참조)

다형성만으로는 OCP, DIP를 지키면서 프로그래밍을 작성할 수 없다 -> 스프링의 DI Container로 해당 문제를 해결 가능

to be continued...

P.S.
모든 설계에 인터페이스를 부여하는 것이 가장 이상적이지만 인터페이스를 도입할 때에는 추상화 과정이 필요하다. 실무에서는 기능 확장할 가능성이 없는 경우, 구체 클래스를 직접 사용하여 별도의 추상화 과정 없이 개발한다.

이런 요소들을 잘 파악하고 효율적으로 잘 설계하는 것이 좋은 개발자가 되는 방법 중 하나라 생각해도 된다.

만약 추후에 기능을 확장해야된다면 refactoring을 통해 인터페이스 도입을 해주면 된다.

0개의 댓글