프로젝트

일반

사용자정보

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 패턴은 이러한 다형성을 활용하여 유연하고 확장 가능한 시스템을 구축하도록 안내합니다.