영호
다형성이란? 본문
개요
우아한테크코스 프롤로그 학습로드맵에 있는 다형성에 대해 공부한 내용을 정리해 보겠습니다 :)
다형성?
단어만 보면 "다양한 형태를 가질 수 있는 성질인가?"라는 생각이 먼저 들었습니다. 위키백과를 보면 다형성을 아래와 같이 설명하고 있습니다.
프로그램 언어의 각 요소들(상수, 변수, 식, 오브젝트, 함수, 메소드 등)이 다양한 자료형(type)에 속하는 것이 허가되는 성질을 가리킨다.
즉, 하나의 객체, 메서드에 다양한 타입들을 갈아 끼울 수 있는 객체지향의 특징이다. 이렇게 말만 보면 잘 이해가 가지 않으니 코드로 적용해 보겠습니다.
다형성을 구현하는 방법에는 오버로딩, 오버라이딩도 있지만 이 글에서는 인터페이스를 통한 다형성에 대해 살펴보겠습니다.
인터페이스를 통한 다형성
고스톱을 할 때, 패를 나눠주는 사람은 한 명이지만, 다양한 기술을 가진 딜러들이 있습니다. 타짜가 나눠줄 수도 있고, 공정한 플레이어가 나눠줄 수도 있습니다. 이처럼 패를 나눠주는 사람(Dealer)은 다양한 타입의 객체가 올 수 있습니다. 코드를 통해 이 예제를 살펴보겠습니다.
Dealer인터페이스
public interface Dealer {
public void deal();
}
패를 나눠주는 Dealer인터페이스를 정의합니다.
손기술이 나쁜 Tajja구현체
public class Tajja implements Dealer{
@Override
public void deal() {
System.out.println("밑장 빼기");
}
}
얍삽한 플레이를 하는 Tajja딜러를 구현합니다.
정직한 PairDealer구현체
public class PairDealer implements Dealer{
@Override
public void deal() {
System.out.println("섞어서 나눠주기");
}
}
공정한 플레이를 하는 pairDealer딜러를 구현합니다.
고스톱 게임
public class GoStop {
private final Dealer dealer;
GoStop(final Dealer dealer) {
this.dealer = dealer;
}
public void run() {
dealer.deal();
}
}
GoStop게임을 진행할 GoStop클래스를 만들고 Dealer를 주입받습니다. 이후, 게임을 진행하기 위해 run메서드를 정의합니다. 해당 메서드는 딜러가 패를 나눠주는 Dealer.deal() 메서드를 호출합니다.
실행을 위한 메인메서드
public class Application {
public static void main(String[] args) {
final GoStop goStop = new GoStop(new Tajja());
goStop.run(); //밑장 빼기
}
}
이제 메인메서드를 생성하고 타짜 딜러가 카드게임을 진행해보겠습니다. 얍삽한 타짜가 카드를 나눠줬기 때문에 "밑장 빼기"가 출력됩니다.
딜러 교체
이제 공정한 딜러인 PairDealer가 카드를 나눠줄 차례입니다. 코드 수정 부분은 메인메서드에서 딜러를 주입해주는 부분의 수정만 일어납니다.
public class Application {
public static void main(String[] args) {
final GoStop goStop = new GoStop(new PairDealer());
goStop.run(); //섞어서 나눠주기
}
}
이번 딜러는 아주 공정하게 카드를 나눠줬습니다.
새로운 나쁜 손기술의 딜러 등장
그런데 갑자기 새로운 타짜 기술인 가운데서 빼기 기술을 사용하는 CenterTajjaDealer가 나타났습니다. 저희는 다형성을 적용해 코드를 구성했기 때문에 기존 코드 수정없이 손쉽게 새로운 Dealer타입을 추가할 수 있습니다.
public class CenterTajjaDealer implements Dealer{
@Override
public void deal() {
System.out.println("가운데서 빼기");
}
}
위 코드처럼 새로운 Dealer코드를 기존 코드 수정 없이 추가를 통해 구현할 수 있습니다. 이후 메인메서드에서 GoStop에 Dealer를 주입해주는 부분만 CenterTajjaDealer로 수정하게 되면, 매우 간단하게 새로운 타입의 Dealer가 추가됩니다.
public class Application {
public static void main(String[] args) {
final GoStop goStop = new GoStop(new CenterTajjaDealer());
goStop.run();
}
}
내가 생각하는 다형성의 이점
이처럼 다형성을 적용한다면, Dealer dealer에 Dealer인터페이스를 구현한 new Tajja(), new CenterTajjaDealer(), new PairDealer()같은 다양한 구현체들을 적용할 수 있습니다.
다형성을 통해 SOLID의 OCP, DIP원칙을 지킬 수 있습니다. 우선, OCP의 경우, 새로운 CenterTajjaDealer를 추가할 때 기존 코드의 변경 없이 새로운 딜러를 추가할 수 있었습니다. 수정엔 닫혀 있고, 확장엔 열려 있는 OCP원칙을 만족했습니다.
그리고 DIP의 경우, GoStop의 Dealer dealer는 Dealer구현체인 Tajja, CenterTajjaDealer, PairDealer에 의존하지 않고 Dealer라는 추상타입에 의존하고 있기 때문에 DIP를 지킬 수 있었습니다.
이처럼 객체지향적인 코드를 짜는데 있어 다형성은 빼놓을 수 없는 중요한 요소라는 생각이 들었습니다. 그리고 다형성은 추후 다양한 패턴의 근간이 된다고 생각하기 때문에 확실하게 잡고 가면 좋은 개념이라는 생각이 듭니다:)
'OOP' 카테고리의 다른 글
DAO(Data Access Object) (4) | 2023.05.01 |
---|---|
[OOP] EnumMap과 함수형 인터페이스로 커맨드 패턴 적용해보기 (0) | 2023.03.26 |
[OOP] SOLID - DIP(의존성 역전 원칙) (2) | 2022.12.23 |
[SOLID] ISP(인터페이스 분리 원칙) (0) | 2022.06.07 |
[OOP] SOLID - LSP(리스코프 치환 원칙) (0) | 2022.06.05 |