반응형

객체 지향 설계 원칙: SOLID

객체 지향 설계에서 SOLID 원칙은 유지보수성과 확장성이 높은 소프트웨어를 개발하기 위해 지켜야 할 다섯 가지 기본 원칙을 의미합니다. 이 글에서는 SOLID의 각 원칙을 자세히 설명하고, 이러한 원칙이 왜 중요한지 살펴보겠습니다.


SOLID란 무엇인가?

SOLID는 객체 지향 설계의 다섯 가지 원칙을 정의한 약어로, 다음과 같은 원칙들로 구성됩니다:

  1. S: 단일 책임 원칙 (Single Responsibility Principle)
  2. O: 개방-폐쇄 원칙 (Open/Closed Principle)
  3. L: 리스코프 치환 원칙 (Liskov Substitution Principle)
  4. I: 인터페이스 분리 원칙 (Interface Segregation Principle)
  5. D: 의존성 역전 원칙 (Dependency Inversion Principle)

이 원칙들은 소프트웨어를 더 유연하고 유지보수 가능하게 만들어줍니다.


1. 단일 책임 원칙 (SRP)

클래스는 단 하나의 책임만 가져야 한다.

설명:

클래스는 하나의 역할만 가져야 하며, 변경의 이유가 하나여야 합니다. 여러 책임이 한 클래스에 섞이면 수정이 어려워지고, 코드 재사용성이 떨어집니다.

예제:
class ReportGenerator {
    public void generateReport() {
    // 보고서 생성 로직
    }

    public void printReport() {
    // 보고서 출력 로직
    }
}

위 클래스는 보고서 생성과 출력 두 가지 책임을 가지고 있습니다. 이를 분리하면:

class ReportGenerator {
    public void generateReport() {
    // 보고서 생성 로직
    }
}

class ReportPrinter {
    public void printReport() {
    // 보고서 출력 로직
    }
}
장점:
  • 클래스가 더 간결해짐.
  • 특정 책임의 변경이 다른 부분에 영향을 미치지 않음.

2. 개방-폐쇄 원칙 (OCP)

클래스는 확장에는 열려 있어야 하지만, 수정에는 닫혀 있어야 한다.

설명:

새로운 기능이 추가될 때 기존 코드를 수정하지 않고 확장할 수 있어야 합니다. 이를 통해 기존 코드의 안정성을 보장할 수 있습니다.

예제:

기존 코드:

class Notification {
    public void send(String type) {
        if (type.equals("Email")) {
	        System.out.println("Send Email");
        } else if (type.equals("SMS")) {
    	    System.out.println("Send SMS");
        }
    }
}

OCP를 적용:

interface Notification {
	void send();
}

class EmailNotification implements Notification {
    @Override
    public void send() {
	    System.out.println("Send Email");
    }
}

class SMSNotification implements Notification {
    @Override
    public void send() {
	    System.out.println("Send SMS");
    }
}
장점:
  • 새로운 알림 타입 추가 시 기존 코드를 수정할 필요 없음.

3. 리스코프 치환 원칙 (LSP)

하위 클래스는 상위 클래스에서 기대하는 동작을 모두 수행할 수 있어야 한다.

설명:

상위 클래스의 객체를 하위 클래스 객체로 대체해도 프로그램의 동작에 문제가 없어야 합니다.

예제:

위반 사례:

class Rectangle {
    private int width;
    private int height;

    public void setWidth(int width) {
	    this.width = width;
    }

    public void setHeight(int height) {
    	this.height = height;
    }

    public int getArea() {
    	return width * height;
    }
}

class Square extends Rectangle {
    @Override
    public void setWidth(int width) {
	    super.setWidth(width);
    	super.setHeight(width);
    }

    @Override
    public void setHeight(int height) {
    	super.setWidth(height);
    	super.setHeight(height);
	}
}

위 코드에서는 사각형(Rectangle) 객체를 기대하는 코드가 정사각형(Square) 객체에서 의도치 않은 동작을 경험할 수 있습니다.

해결:

직사각형과 정사각형을 별도 클래스로 설계.


4. 인터페이스 분리 원칙 (ISP)

클라이언트는 자신이 사용하지 않는 메서드에 의존하지 않아야 한다.

설명:

하나의 거대한 인터페이스 대신, 더 작고 구체적인 인터페이스로 분리해야 합니다.

예제:

위반 사례:

interface Worker {
    void work();
    void eat();
}

class Robot implements Worker {
    @Override
    public void work() {
	    System.out.println("Robot working");
    }

    @Override
    public void eat() {
    	// 로봇은 먹지 않음
    }
}

ISP 적용:

interface Workable {
	void work();
}

interface Eatable {
	void eat();
}

class Robot implements Workable {
    @Override
    public void work() {
	    System.out.println("Robot working");
    }
}
장점:
  • 불필요한 메서드 의존 제거.

5. 의존성 역전 원칙 (DIP)

고수준 모듈은 저수준 모듈에 의존해서는 안 된다. 둘 다 추상화에 의존해야 한다.

설명:

구체적인 구현보다 인터페이스와 같은 추상화에 의존하도록 설계해야 합니다.

예제:

위반 사례:

class Keyboard {}
class Monitor {}

class Computer {
    private Keyboard keyboard;
    private Monitor monitor;

    public Computer() {
        this.keyboard = new Keyboard();
        this.monitor = new Monitor();
    }
}

DIP 적용:

interface InputDevice {}
class Keyboard implements InputDevice {}

interface OutputDevice {}
class Monitor implements OutputDevice {}

class Computer {
    private InputDevice inputDevice;
    private OutputDevice outputDevice;

    public Computer(InputDevice inputDevice, OutputDevice outputDevice) {
    	this.inputDevice = inputDevice;
    	this.outputDevice = outputDevice;
    }
}
장점:
  • 의존성 주입을 통해 유연성 증가.

SOLID 원칙이 필요한 이유

  1. 유지보수성: 코드를 더 쉽게 수정하고 확장할 수 있습니다.
  2. 재사용성: 모듈화된 설계를 통해 코드 재사용이 가능.
  3. 확장성: 요구사항 변경에 유연하게 대응.
  4. 가독성: 명확하고 직관적인 코드 작성.

SOLID 원칙을 준수하면, 변화에 강하고 확장 가능한 소프트웨어를 설계할 수 있습니다. 이를 실천함으로써 소프트웨어 개발의 품질을 한 단계 높여보세요!

 

 

반응형

+ Recent posts