SOLID

LJM·2023년 3월 12일
0

Java

목록 보기
19/33

객체지향설계 5가지 원칙

Single Responsibility Principle (SRP)

  • 단일 책임 원칙: 클래스는 하나의 책임만 가져야 하며, 그 책임은 클래스가 완전히 캡슐화해야 합니다. 이 원칙을 따르면 클래스가 바뀌어야 하는 이유가 하나뿐이 되어, 코드의 유지 보수가 쉬워집니다.

Open/Closed Principle (OCP)

  • 개방-폐쇄 원칙: 소프트웨어의 구성요소(클래스, 모듈, 함수 등)는 확장에는 열려 있어야 하며, 수정에는 닫혀 있어야 합니다. 즉, 기존의 코드를 변경하지 않고도 새로운 기능을 추가할 수 있어야 합니다.

Liskov Substitution Principle (LSP)

  • 리스코프 치환 원칙: 부모 클래스와 호환되는 자식 클래스를 만들어야 합니다. 즉, 자식 클래스는 부모 클래스의 책임을 무너뜨리지 않으면서 확장이 가능해야 합니다.

Interface Segregation Principle (ISP)

  • 인터페이스 분리 원칙: 한 클래스는 자신이 사용하지 않는 인터페이스는 구현하지 않아야 합니다. "클라이언트가 필요하지 않은 메서드에 의존하지 않아야 한다"는 원칙입니다.

Dependency Inversion Principle (DIP)

  • 의존 역전 원칙: 고수준 모듈은 저수준 모듈에 의존하면 안 되며, 둘 다 추상화에 의존해야 합니다. 이 원칙은 상위 수준의 클래스가 하위 수준의 클래스에 직접적으로 의존하지 않도록 설계를 해야 함을 의미합니다.

일반적인 접근 방식 (DIP를 따르지 않는 경우)

class LightBulb {
    void turnOn() {
        System.out.println("LightBulb: Bulb turned on...");
    }
    void turnOff() {
        System.out.println("LightBulb: Bulb turned off...");
    }
}

class ElectricPowerSwitch {
    private LightBulb lightBulb;

    public ElectricPowerSwitch(LightBulb lightBulb) {
        this.lightBulb = lightBulb;
    }

    void press() {
        System.out.println("Switch pressed");
        lightBulb.turnOn();
    }
}

위의 예시에서 ElectricPowerSwitch는 LightBulb 클래스에 의존적입니다. 즉, 다른 종류의 전구나 전원을 다루려면 새로운 클래스를 만들거나 기존 클래스를 수정해야 하므로 확장성이 떨어집니다.

의존 역전 원칙을 적용한 접근 방식

interface Switchable {
    void turnOn();
    void turnOff();
}

class LightBulb implements Switchable {
    @Override
    public void turnOn() {
        System.out.println("LightBulb: Bulb turned on...");
    }
    @Override
    public void turnOff() {
        System.out.println("LightBulb: Bulb turned off...");
    }
}

class ElectricPowerSwitch {
    private Switchable device;

    public ElectricPowerSwitch(Switchable device) {
        this.device = device;
    }

    void press() {
        System.out.println("Switch pressed");
        device.turnOn();
    }
}

Switchable은 추상화(인터페이스)를 제공하고, ElectricPowerSwitch와 LightBulb 모두 이 추상화에 의존합니다. 이로 인해 ElectricPowerSwitch는 이제 LightBulb에 직접적으로 의존하지 않게 되어 다양한 Switchable 객체를 다룰 수 있게 됩니다. 이는 코드의 유연성과 확장성을 향상시킵니다.

예제에서의 "저수준 모듈(Low-level Module)"은 LightBulb 클래스입니다. 이 모듈은 개별 기능(전구 켜기, 끄기)을 수행하는 실제 로직을 구현합니다. 이러한 저수준 모듈은 실제 '일'을 하는 모듈이라고 생각할 수 있습니다.

"고수준 모듈(High-level Module)"은 ElectricPowerSwitch 클래스입니다. 이 모듈은 저수준 모듈인 LightBulb을 사용하여 더 복잡한 기능(스위치 누르기)을 구현합니다. 고수준 모듈은 비즈니스 로직이나 사용자 인터페이스 등을 관리하고, 여러 저수준 모듈을 조합하여 더 큰 기능을 구현하는 모듈이라고 생각할 수 있습니다.

"의존 역전 원칙(Dependency Inversion Principle)"을 적용하면, 고수준 모듈인 ElectricPowerSwitch는 저수준 모듈인 LightBulb에 직접적으로 의존하지 않습니다. 대신, 둘 다 Switchable이라는 추상화(인터페이스)에 의존하게 됩니다. 이로써 고수준 모듈과 저수준 모듈 사이의 결합도가 낮아지고, 유지보수와 확장성이 향상됩니다.

profile
게임개발자 백엔드개발자

0개의 댓글