Spring

[중앙정보처리학원] Spring* 객체지향 설계원칙 SOLID

해보구 2024. 5. 13. 14:40

SOLID

SOLID는 객체 지향 프로그래밍에서 유지보수와 확장성을 높이기 위한 다섯 가지 설계 원칙

 

이 원칙들은 객체 지향 프로그램을 개발하고 설계할 때 유용함

 

 

 

다섯 가지 SOLID 원칙

  1. SRP (Single Responsibility Principle): 단일 책임 원칙
  • 한 클래스는 단 하나의 책임을 가져야 함, 클래스가 변경되어야 하는 이유는 단 하나의 이유.
  1. OCP (Open-Closed Principle): 개방-폐쇄 원칙
  • 기존 코드를 변경하지 않으면서] 기능을 확장할 수 있도록 설계해야 함.
  1. LSP (Liskov Substitution Principle): 리스코프 치환 원칙
  • 서브 타입은 언제나 기반 타입으로 교체가능
  1. ISP (Interface Segregation Principle): 인터페이스 분리 원칙
  • 인터페이스는 클라이언트에 특화됨, 클라이언트가 사용하지 않는 메서드는 포함X
  1. DIP (Dependency Inversion Principle): 의존 역전 원칙
  • 상위 수준 모듈은 하위 수준 모듈에 의존X,   추상화는 구체적인 사항에 의존X

 

SRP : 단일 책임 원칙

public class User {
    private String username;
    private String password;
    
    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
    
    public boolean isValid() {
        // 유효성 검사
        return true;
    }
    
    public void save() {
        // 데이터 저장
    }
}

 

정보만 가지고 있게하고 검사만하고 저장만해라 

 

 

OCP : 개방-폐쇄 원칙

skip

 

 

LSP : 리스코프 치환 원칙

public class Rectangle {
    protected int width;
    protected int height;

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

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

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }

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

public class Square extends Rectangle {
    @Override
    public void setWidth(int width) {
        this.width = width;
        this.height = width;
    }

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

public class LspExample {
    public static void main(String[] args) {
        Rectangle rectangle = new Rectangle();
        rectangle.setWidth(5);
        rectangle.setHeight(10);
        System.out.println(rectangle.calculateArea()); // 50

        Square square = new Square();
        square.setWidth(5);
        square.setHeight(10);
        System.out.println(square.calculateArea()); // 100
    }
}

 

 

ISP : 인터페이스 분리 원칙

 

public interface Shape {
    double calculateArea();
    double calculateVolume();
}

public class Rectangle implements Shape {
    private double width;
    private double height;

    public double calculateArea() {
        return width * height;
    }

    public double calculateVolume() {
        throw new UnsupportedOperationException();
    }
}

public class Cube implements Shape {
    private double width;
    private double height;
    private double depth;

    public double calculateArea() {
        return 2 * (width * height + width * depth + height * depth);
    }

    public double calculateVolume() {
        return width * height * depth;
    }
}

인터페이스를 하나로 쓰지말고 넓이구하는 인터페이스1 , 부피구하는 인터페이스 1 이런식으로 나눠서 구현해라

 

 

public interface Area {
    double calculateArea();
}

public interface Volume {
    double calculateVolume();
}

public class Rectangle implements Area {
    private double width;
    private double height;

    public double calculateArea() {
        return width * height;
    }
}

public class Cube implements Area, Volume {
    private double width;
    private double height;
    private double depth;

    public double calculateArea() {
        return 2 * (width * height + width * depth + height * depth);
    }

    public double calculateVolume() {
        return width * height * depth;
    }
}



이런식으로

 

DIP : 의존성 역전의 원칙

public class RedLight {
    public void turnOn() {
        System.out.println("Red Light turned on");
    }
}

public class Switch {
    private RedLight light;
    
    public Switch() {
        this.light = new RedLight();
    }
    
    public void flip() {
        if (light != null) {
            light.turnOn();
        }
    }
}

고차원 모듈은 저차원 모듈에 의존해서는 안된다

추상화는 세부사항에 의존해서는 안된다. 세부사항은 추상화에 의존해야 한다.

 

DIP를 적용하면 다음과 같이 코드를 수정

 

public interface Light {
    void turnOn();
}

public class RedLight implements Light {
    @Override
    public void turnOn() {
        System.out.println("Red Light turned on");
    }
}

public class Switch {
    private Light light;
    
    public Switch(Light light) {
        this.light= light;
    }
    
    public void flip() {
        if (light!= null) {
            light.turnOn();
        }
    }
}