카테고리 없음

[SOLID] 단일 책임 원칙 - SRP(Single Responsibility Principle)

장일규 2024. 1. 7. 13:48

 

이번에는 좋은 객체 지향 설계를 위한 방법 중 하나인

단일 책임 원칙SRP(Single Responsibility Principle)에 대해서 알아보겠음다..!

 

단일 책임 원칙..?

말 그대로 "클래스는 단 한 개의 책임을 가져야 한다" 규칙을 의미한다.

 

실생활 에서 SRP 규칙을 적용해서 이해보려고 한다.

 

우리가 필수적으로 사용하는 핸드폰에 기능들을 생각해보자

 

전화, 카메라, 인터넷 검색 등등 여러가지 기능이 있다.

우선, SRP를 위반하는 핸드폰 클래스를 코드로 작성해보자..!

// SRP를 위반하는 핸드폰 코드
public class CellPhone {
    private int batteryLevel;

    // 전화 걸기 동작 수행
    public void makeCall(String phoneNumber) {
         consumeBattery();
    }

    // 메시지 전송 동작 수행
    public void sendMessage(String recipient, String message) {
         consumeBattery();
    }

    // 인터넷 브라우징 동작 수행
    public void browseInternet(String url) {
         consumeBattery();
    }

    // 사진 촬영 동작 수행
    public void capturePhoto() {
         consumeBattery();
    }

    // 비디오 녹화 동작 수행
    public void recordVideo() {
         consumeBattery();
    }

    // 배터리 소모 로직
    private void consumeBattery() {
        batteryLevel--;
    }

}

 

CellPhone 클래스는 통화, 메시지 전송, 인터넷 브라우징, 카메라 관련 기능을 모두 책임지면서 동시에 배터리 소모까지 관리하고 있다.

 

consumeBattery 함수는 여러 기능에서 호출되는데, 이로 인해 각각의 기능이 배터리 소모와 강하게 결합되어 있다.

 변경이 발생할 경우 다른 기능에도 영향을 미칠 가능성이 있다.

예를 들어서 배터리 소모 로직이 변경되면 통화, 메시지 전송, 인터넷 브라우징, 사진 촬영, 비디오 녹화와 관련된 모든 코드를 수정해야 할 수 있다.

 

실생활에서는 공간도 절약할 수 있고 사용하기 편하지만,

객체지향적인 코드 관점에서는 단일 책임 원칙이 위반 되는 것이다.

 

그러면 어떻게  SRP를 준수하도록 변경해야할까..?

SRP를 적용하는 것은 어렵지 않다.

 

각각의 기능에 해당하는 책임을 분리하면 된다.

 

변경이 한 기능에만 영향을 미치도록 설계할 수 있으며,

 

 코드의 유지보수성과 확장성을 향상시킬 수 있다.

// 모든 기능을 통합하는 CellPhone 클래스
public class CellPhone {
    private PhoneFunctionality phoneFunctionality;
    private MessagingFunctionality messagingFunctionality;
    private InternetBrowsingFunctionality internetBrowsingFunctionality;
    private CameraFunctionality cameraFunctionality;

    public CellPhone(PhoneFunctionality phoneFunctionality, MessagingFunctionality messagingFunctionality,
                     InternetBrowsingFunctionality internetBrowsingFunctionality, CameraFunctionality cameraFunctionality) {
        this.phoneFunctionality = phoneFunctionality;
        this.messagingFunctionality = messagingFunctionality;
        this.internetBrowsingFunctionality = internetBrowsingFunctionality;
        this.cameraFunctionality = cameraFunctionality;
    }
}

// 전화 기능을 담당하는 클래스
class PhoneFunctionality {
    public void makeCall(String phoneNumber) {
        // 전화 걸기 동작 수행
    }

    public void receiveCall() {
        // 전화 받기 동작 수행
    }
}

// 메시지 기능을 담당하는 클래스
class MessagingFunctionality {
    public void sendMessage(String recipient, String message) {
        // 메시지 전송 동작 수행
    }

    public void receiveMessage() {
        // 메시지 수신 동작 수행
    }
}

// 인터넷 브라우징 기능을 담당하는 클래스
class InternetBrowsingFunctionality {
    public void browseInternet(String url) {
        // 인터넷 브라우징 동작 수행
    }
}

// 카메라 기능을 담당하는 클래스
class CameraFunctionality {
    public void capturePhoto() {
        // 사진 촬영 동작 수행
    }

    public void recordVideo() {
        // 비디오 녹화 동작 수행
    }
}

// 배터리 소모 로직을 담당하는 클래스
class BatteryManager {
    private int batteryLevel;

    public void consumeBattery() {
        // 배터리 소모 로직
        batteryLevel--;
    }
}
공용 클래스 Multi PurposeBed { void bookshelf(); 무효 저장공간(); 빈 책상(); }
 
 
1. 책장 2. 수납공간 3. 책상
 
3. 인터넷 검색