반응형

단일 책임 원칙은 클래스, 객체 혹은 모듈이 하나의 책임을 가져야 한다는 원칙이다.

그렇다면 책임은 무엇일까?

책임이란 클래스 또는 객체가 하나의 작업이나 기능을 수행해야한다는 원칙이다.

그런데 책임이란 이런 작업이나 기능이보다는 역할이라는 말이 더 적합하다.

비디오 가게 코드를 예시로 보면

import java.util.ArrayList;
import java.util.List;

public class VideoStore {
    private List<Video> videos;

    public VideoStore() {
        videos = new ArrayList<>();
    }

    public void addVideo(Video video) {
        videos.add(video);
    }

    public void rentVideo(String title) {
        for (Video video : videos) {
            if (video.getTitle().equalsIgnoreCase(title)) {
                video.rent();
                return;
            }
        }
    }

    public void returnVideo(String title) {
        for (Video video : videos) {
            if (video.getTitle().equalsIgnoreCase(title)) {
                video.returnVideo();
                return;
            }
        }
    }
}

VideoStore 클래스는 비디오 가게에 비디오 리스트를 가지고 있고 추가, 대여, 반납 하는 기능이 있다.

VideoStore 클래스는 단일 책임 원칙이 잘 지켜지고 있다. 비디오 가게라는 역할에 맞는 기능들만을 가지고 있기 때문이다.

단일 책임 원칙을 지키게되면 좀 더 객체지향적으로 프로그래밍 할 수 있고, 다음과 같은 장점을 가질 수 있다.

  1. 높은 응집도
  2. 유지보수성
  3. 변경 용이성
import java.util.ArrayList;
import java.util.List;

public class VideoStore {
    private List<Video> videos;
    private List<User> users;

    public VideoStore() {
        videos = new ArrayList<>();
    }

    public void addVideo(Video video) {
        videos.add(video);
    }

    public void rentVideo(String title) {
        for (Video video : videos) {
            if (video.getTitle().equalsIgnoreCase(title)) {
                video.rent();
                return;
            }
        }
    }

    public void returnVideo(String title) {
        for (Video video : videos) {
            if (video.getTitle().equalsIgnoreCase(title)) {
                video.returnVideo();
                return;
            }
        }
    }
    
    public void addUser(User user) {
        users.add(user);
    }
}

위의 코드는 단일 책임 원칙이 깨진 코드이다.

VideoStore가 비디오만 관리하는 것이 아니라 사용자 정보도 관리하기 때문에 VideoStore는 두 가지 역할을 가지고 있다.

물론 이런 경우에도 기능을 정상적으로 작동할 것이고 문제가 없을 가능성이 크다.

다만 이렇게 단일 책임 원칙이 깨지게 되면, 클래스의 역할 즉 클래스가 해야할 일은 모호해지고, 변경에 대한 복잡도가 증가하게 되어 유지보수성이 떨어진다.

SRP를 지킨 코드

VideoManager

public class VideoManager {
    private List<Video> videos = new ArrayList<>();

    public void addVideo(Video video) {
        videos.add(video);
    }

    public void rentVideo(String title) {
        for (Video video : videos) {
            if (video.getTitle().equalsIgnoreCase(title)) {
                video.rent();
                return;
            }
        }
    }

    public void returnVideo(String title) {
        for (Video video : videos) {
            if (video.getTitle().equalsIgnoreCase(title)) {
                video.returnVideo();
                return;
            }
        }
    }
}

UserManager

public class UserManager {
    private List<User> users = new ArrayList<>();

    public void addUser(User user) {
        users.add(user);
    }
}

VideoStore

public class VideoStore {
    private VideoManager videoManager = new VideoManager();
    private UserManager userManager = new UserManager();

    public void registerVideo(Video video) {
        videoManager.addVideo(video);
    }

    public void registerUser(User user) {
        userManager.addUser(user);
    }
    
    // business
}

비디오를 관리하고 사용자를 관리하는 것은 각각 VideoManager와 UserManager가 책임을 가지고 있다

그리고 이 Manager들을 활용하여 VideoStore Business 로직을 구현 한다

반응형

+ Recent posts