ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SOLID - Interface segregation(인터페이스 분리법칙) 파헤치기
    Java/디자인패턴 2024. 10. 22. 16:19
    반응형

    Interface segregation

    **Interface Segregation Principle (ISP)**는 SOLID 원칙 중 하나로, 클라이언트는 사용하지 않는 메서드에 의존하지 않아야 한다는 개념입니다. 즉, 하나의 큰 인터페이스보다는 여러 개의 작은 인터페이스로 분리하여, 각 클래스가 실제로 필요한 기능만을 구현하도록 해야 한다는 원칙입니다.

     

    문제점:

    위 코드에서는 Worker 인터페이스가 두 가지 책임(일하기와 먹기)을 모두 가지고 있습니다. 하지만, 로봇(Robot)은 먹는(eat()) 행동을 필요로 하지 않습니다. 이는 **Interface Segregation Principle (ISP)**를 위반하는 상황입니다. Robot 클래스는 eat() 메서드를 구현하지 않아야 하지만, 인터페이스 때문에 이 메서드를 오버라이드할 수밖에 없으며, 결국 예외를 던지는 코드를 작성하게 됩니다. 이는 인터페이스가 너무 많은 책임을 지고 있다는 신호입니다.

     

    ISP에 위배된 코드

    // Interface for workers
    public interface Worker {
        void work();
        void eat();
    }
    
    // Class representing a regular worker
    public class Employee implements Worker {
        @Override
        public void work() {
            System.out.println("Employee is working");
        }
    
        @Override
        public void eat() {
            System.out.println("Employee is eating");
        }
    }
    
    // Class representing a robot
    public class Robot implements Worker {
        @Override
        public void work() {
            System.out.println("Robot is working");
        }
    
        @Override
        public void eat() {
            // Robots do not eat
            throw new UnsupportedOperationException("Robots do not eat");
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Worker employee = new Employee();
            employee.work(); // Employee is working
            employee.eat(); // Employee is eating
    
            Worker robot = new Robot();
            robot.work(); // Robot is working
            robot.eat(); // Throws UnsupportedOperationException
        }
    }

     

    개선 방법:

    Worker 인터페이스를 작은 인터페이스로 분리하여, 각 클래스가 자신이 필요한 인터페이스만 구현하도록 만듭니다. 예를 들어, "일하는 기능"을 정의한 인터페이스와 "먹는 기능"을 정의한 인터페이스를 분리할 수 있습니다.

     

    개선된 코드

    // Work 관련 기능만 정의한 인터페이스
    public interface Workable {
        void work();
    }
    
    // Eat 관련 기능만 정의한 인터페이스
    public interface Eatable {
        void eat();
    }
    
    // Regular worker는 Workable과 Eatable 둘 다 구현
    public class Employee implements Workable, Eatable {
        @Override
        public void work() {
            System.out.println("Employee is working");
        }
    
        @Override
        public void eat() {
            System.out.println("Employee is eating");
        }
    }
    
    // Robot은 Workable만 구현 (Eatable은 필요 없음)
    public class Robot implements Workable {
        @Override
        public void work() {
            System.out.println("Robot is working");
        }
    }
    
    // Main 클래스
    public class Main {
        public static void main(String[] args) {
            Workable employee = new Employee();
            employee.work(); // Employee is working
    
            Eatable eatingEmployee = (Eatable) employee;
            eatingEmployee.eat(); // Employee is eating
    
            Workable robot = new Robot();
            robot.work(); // Robot is working
    
            // 로봇은 더 이상 eat()을 호출할 수 없음
        }
    }

    개선된 코드 설명:

    1. Workable 인터페이스: work() 메서드만 정의된 인터페이스로, "일할 수 있는" 객체들만 이 인터페이스를 구현합니다.
    2. Eatable 인터페이스: eat() 메서드만 정의된 인터페이스로, "먹을 수 있는" 객체들만 이 인터페이스를 구현합니다.
    3. Employee 클래스: 일반적인 직원은 일도 하고, 식사도 하므로 Workable과 Eatable 인터페이스 둘 다 구현합니다.
    4. Robot 클래스: 로봇은 일만 하고, 먹을 필요가 없으므로 Workable 인터페이스만 구현합니다. 이제 Robot은 불필요한 eat() 메서드를 구현할 필요가 없습니다.
    5. Main 클래스: 이제 Employee와 Robot이 각자의 역할에 맞는 인터페이스만 구현하므로, Robot이 eat() 메서드를 호출하려고 시도하는 문제를 피할 수 있습니다.

    ISP 준수:

    이 개선된 설계는 **Interface Segregation Principle (ISP)**를 준수합니다. 각 클래스는 자신이 필요한 기능만을 제공하는 인터페이스를 구현하도록 되어 있습니다. 로봇은 이제 불필요한 eat() 메서드를 구현하지 않아도 되며, 인터페이스의 책임이 분리되어 코드가 더 명확하고 확장 가능해졌습니다.

    반응형

    댓글

Designed by Tistory.