GRASP 패턴: Polymorphism (다형성)
Prof. Jong Min Lee이(가) 약 한달 전에 추가함
GRASP 패턴: Polymorphism (다형성) - 간단한 설명과 예시¶
핵심 아이디어: 객체의 타입에 따라 "어떻게" 행동할지를 결정하는 책임을 객체 스스로에게 할당합니다. 즉, 동일한 메시지를 보내더라도 객체의 실제 종류에 따라 다른 방식으로 응답하도록 설계하는 것입니다.
간단한 설명:
다형성은 "여러 가지 형태를 가질 수 있는 능력"을 의미합니다. 객체 지향 프로그래밍에서는 이를 통해 유연성과 확장성을 높일 수 있습니다. 상위 타입의 인터페이스나 추상 클래스를 통해 여러 하위 타입의 객체를 다룰 수 있으며, 각 하위 타입은 자신만의 방식으로 동작을 구현합니다. 외부에서는 하위 타입의 구체적인 종류를 알 필요 없이 상위 타입의 인터페이스를 통해 일관된 방식으로 객체와 상호작용할 수 있습니다.
예시:
간단한 도형 클래스 계층을 생각해 봅시다. Shape
이라는 추상 클래스가 있고, 이를 상속받는 Rectangle
, Circle
, Triangle
클래스가 있다고 가정합니다. 각 도형은 자신의 넓이를 계산하는 calculateArea()
라는 메서드를 가지고 있습니다.
// 추상 클래스
abstract class Shape {
public abstract double calculateArea();
}
// 사각형 클래스
class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public double calculateArea() {
return width * height;
}
}
// 원 클래스
class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
}
// 삼각형 클래스
class Triangle extends Shape {
private double base;
private double height;
public Triangle(double base, double height) {
this.base = base;
this.height = height;
}
@Override
public double calculateArea() {
return 0.5 * base * height;
}
}
public class ShapeCalculator {
public static void main(String[] args) {
Shape rectangle = new Rectangle(5, 10);
Shape circle = new Circle(3);
Shape triangle = new Triangle(4, 6);
// Shape 타입의 변수로 각 도형 객체를 참조하고,
// 동일한 메서드 호출에도 불구하고 각 객체의 실제 타입에 따라 다른 결과가 나옵니다.
System.out.println("Rectangle 넓이: " + rectangle.calculateArea()); // 출력: Rectangle 넓이: 50.0
System.out.println("Circle 넓이: " + circle.calculateArea()); // 출력: Circle 넓이: 28.274333882308138
System.out.println("Triangle 넓이: " + triangle.calculateArea()); // 출력: Triangle 넓이: 12.0
}
}
이 예시에서 다형성이 적용된 부분:
Shape
이라는 공통된 인터페이스 (calculateArea()
메서드)를 통해Rectangle
,Circle
,Triangle
객체를 다룰 수 있습니다.Shape
타입의 변수 (rectangle
,circle
,triangle
)는 각각 다른 하위 타입의 객체를 참조할 수 있습니다.calculateArea()
메서드를 호출했을 때, 어떤 하위 타입의 객체인지에 따라 실제로 실행되는 코드가 달라집니다. 사각형은 가로 * 세로로, 원은 $\pi r2$로, 삼각형은 0.5 * 밑변 * 높이로 넓이를 계산합니다.
다형성의 장점:
- 유연성: 새로운 도형 클래스를 추가하더라도
ShapeCalculator
의 코드를 크게 수정할 필요가 없습니다. 단순히Shape
을 상속받고calculateArea()
메서드를 구현하기만 하면 됩니다. - 확장성: 시스템을 쉽게 확장할 수 있습니다. 새로운 기능을 추가할 때 기존 코드를 수정하기보다는 새로운 클래스를 추가하는 방식으로 처리할 수 있습니다.
- 결합도 감소: 상위 타입에 의존하고 하위 타입의 구체적인 종류에 대한 의존성을 줄여 클래스 간의 결합도를 낮춥니다.
- 코드 재사용성 증가: 공통된 인터페이스를 통해 다양한 객체를 일관된 방식으로 처리할 수 있어 코드 재사용성을 높입니다.
결론적으로, 다형성은 객체 지향 설계에서 중요한 개념이며, GRASP 패턴은 이러한 다형성을 활용하여 유연하고 확장 가능한 시스템을 구축하도록 안내합니다.