본문 바로가기
자바

객체 지향과 다형성 그리고 SOLID

by 참새는 짹짹 2021. 1. 5.


객체 지향 프로그래밍


말 그대로 '객체'를 지향하는 프로그래밍.

코드를 단순한 명령어가 아닌 '객체'로서 바라봄

객체
  • 한 묶음으로 상태 값기능을 가지는 현실 세계의 사물과 같은 개념
  • 객체 간 데이터 교환과 관계를 통해 작업을 진행

다형성


필요한 기능을 정의하여 그 기능을 가진 객체들을 유연하게 바꿔가며 사용할 수 있음

객체 또는 사용자가 필요한 기능을 연결고리(인터페이스)로 정의하고 이를 사용

그럼 이 자리에는 연결고리를 갖고 있는(인터페이스를 구현한) 객체가 들어감으로써

서로 다른 객체여도 사용자가 필요로 하는 연결고리만 갖고 있으면 정상 동작을 보증

예시

노트북에 USB-C 단자라는 연결고리가 있다면 이 연결고리를 통해 64GB 용량을 가지는 메모리, 128GB 용량을

가지는 메모리와 같이 용량과 성능, 브랜드에 상관없이 관계를 가질 수 있다

더 나아가 usb 케이블을 통해 모니터, 키보드, 충전기 등과도 정해진 연결고리만 맞으면 관계를 가질 수 있다

이는 연결고리만 맞으면 된다는 극단적인 예시를 든 것이고 일반적인 개념은

  • 연결고리 : 길찾기 기능
  • 연결고리를 갖는 부품 : 내비게이션, 스마트폰

이와 같이 있고 사용자가 길찾기 기능을 사용한다고 하면 길찾기 기능이 있는 기기를 사용한다고만

선언하면 이에 대해서는 내비게이션이든 스마트폰이든 사용할 수가 있다

더불어 사용자는 사실 길찾기 기능만 있으면 된다고 할 때 둘 중 어떤 것을 쓴다해도 신경 쓸 필요 없고 몰라도 된다

자바

자바에서는 이 연결고리를 인터페이스로 하여 제공한다

public interface Navi {
	public void navigate();
}

다음과 같이 길찾기 기능을 갖고 있는 인터페이스가 있고 이를 자동차라는 객채(클래스)에서 사용하게 하고 싶다면

public class Car {
	private Navi navi;

	public void setNavi(Navi navi) {
		this.Navi = navi
	}

	public void navigate() {
		navi.navigate();
	}
}

이렇게 외부에서 Navi 인터페이스를 받아 Navi 인터페이스를 구현한 객체를 받으면 된다

자동차는 길찾기 기능을 가진 부품만 있으면 되기에 그 부품이 내비게이션이든 스마트폰이든 신경 쓰지 않아도 된다

외부에서는

Car car = new Car();
Navi navi = new Navigation();
// Navi navi = new SmartPhone();
car.setNavi(navi);

이처럼 Navi 인터페이스를 구현한 Navigation()이나 SmartPhone()을 같은 Navi 인터페이스에 담아 Car에 세

팅해주면 된다

한계

처음에는 이정도만 할 수 있어도 굉장히 유연하다고 생각이 들지만 결국 뒤에 나올 SOLID 원칙에서 보자면

Navigation 객체에서 SmartPhone 객체를 사용한다 하면

// Navi navi = new Navigation();
Navi navi = new SmartPhone();

으로 변경이 불가피하고(OCP 위배) 자동차 객체(클래스)에서는 담는 건 인터페이스에만 의존하지만 외부에서는

결국 구현체로 구현하며 구현체에 의존하고 있다 (DIP 위배)

이를 해결하기 위해

FileInputStream fis = new FileInputStream("설정파일 경로");
Scanner scan = new Scanner(fis);
String className = scan.nextLine();

Class clazz = Class.forName(className);
Car car = new Car();
Navi navi = (Navi)clazz.newInstance();
car.setNavi(navi);

이처럼 설정파일을 따로 두면 설정파일에서는 변경이 필요하겠지만

동작을 위한 코드에는 일체 변경 없이 Navigation과 SmartPhone 모두 자유롭게 사용할 수 있다

참고로 스프링에서는 이러한 작업들을 내부적으로 지원해주기 때문에

알게 모르게 좋은 객체 지향 설계를 강제하고 있다고 볼 수 있다

SOLID


좋은 객체 지향 설계의 5가지 원칙이라고 원칙들의 앞글자만 따와서 'SOLID'라고 한다

  • SRP (Single responsibility principle)
단일 책임 원칙
👨🏻‍💻
한 클래스는 하나의 책임만을 가져야 한다

하나의 책임이라는 말에 애매한 부분이 많지만 결국 뜻하는 바는

'변경에 있어 변경되는 클래스가 맡고 있는 하나의(최소의) 책임만 변경될 수 있도록 설계해야 한다'

라고 본다

  • OCP (Open/Closed principle)
개방-폐쇄 원칙
👨🏻‍💻
확장에는 열려있고 변경에는 닫혀 있어야 한다

앞서 말한 다형성에서 연결고리만 선언해서 사용한다 했을 때

이 연결고리를 갖는 부품들을 새로 만듦으로써 확장을 할 수 있고

그 밖에 연결고리를 사용하는 부분이나 다른 부분에는 일체 변경은 없다

  • LSP (Liskov substitution principle)
리스코프 치환 원칙
👨🏻‍💻
객체는 프로그램의 정확성을 깨지않고 치환이 가능해야 한다

연결고리를 갖는(인터페이스를 구현한) 객체는 연결고리(인터페이스)에서 의도한 대로 구현 되어야 한다

연결고리를 갖고 있지만 엉뚱한 기능을 한다면 프로그램 정확성이 깨지고

연결고리로서 의미를 상실하게 된다

  • ISP (Interface segregation principle)
인터페이스 분리 원칙
👨🏻‍💻
인터페이스는 범용적이기 보다 분리하여 최소한의 메서드만 제공해야 한다

여러 기능을 요구하는 연결고리를 갖기 보다 하나의 기능을 요구하는 연결고리를 여러 개 갖는 게 좋다

  • DIP (Dependency inversion principle)
의존관계 역전 원칙
👨🏻‍💻
구체화에 의존하지 말고 추상화에 의존해야 한다

사용하는 객체에 직접 의존하지 말고 연결고리(인터페이스)에 의존해야 한다

대신 객체는 연결고리를 가져야(인터페이스를 구현해야) 하기 때문에 이에 의존관계가 역전되었다 한다

참고


스프링 핵심 원리 - 기본편 - 인프런
스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다. 초급 프레임워크 및 라이브러리 웹 개발 서버 개발 Back-End Spring 객체지향 온라인 강의 직접 자바 애플리케이션을 만들어가며 스프링의 핵심 원리를 이해하고, 객체 지향 설계와 스프링 컨테이너, 스프링 빈 등 스프링 백엔드 핵심 기능에 대해 학습합니다.
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard
자바 객체지향 강의 33강 - 새로운 객체로 바꾸기(문자열을 읽어서 객체로 만들기)
좋아요~!!! 꾸욱!!!~이 강의는 Java 프로그래밍을 "제대로 공부해 보려는 사람들"을 위해 마련된 강의입니다.자바 언어를 배울 때는 자연스럽게 프로그램을 만드는 방법을 함께 학습해야만 합니다.절차를 작성할 능력도 모자라고 함수를 사용하는 이유도 모르고 객체를 사용하는 이유도...
https://youtu.be/YZzpGtpW2h0


'자바' 카테고리의 다른 글

익명 클래스, 함수형 인터페이스 그리고 람다  (0) 2021.03.14

댓글