[Java] Solid란?
Java

[Java] Solid란?

반응형

Solid를 쓰는 이유?

객체지향 설계가 더 쉬워지고, 유지보수와 확장도 쉬워짐

 

1. SRP(Single Responsibility Principle) : 단일 책임 원칙

"어떤 클래스를 변경해야 하는 이유는 오직 하나뿐이어야 한다."

- 하나의 객체가 하나의 책임을 갖는 것

- 즉, 하나의 객체가 자신이 할 수 있는 것해야 하는 것수행할 수 있도록 설계되어야 한다!

 

SRP를 지켜야 하는 이유

응집도와 결합도 관점에서 접근해야 한다.

 

응집도

- 한 프로그램 요소가 얼마나 뭉쳐있는가를 나타내는 척도.

- 응집도가 높은 클래스는 하나의 책임에 집중하고, 독립성이 높아져 재사용이나 기능의 수정, 유지보수가 용이하다.

 

결합도

- 클래스 간의 상호 의존 정도.

- 결합도가 낮으면 클래스간의 상호 의존성이 줄어들어 객체의 재사용이나 수정, 유지보수가 용이하다.

 

Example)

- SRP가 지켜지지 않은 경우

public class Person {
	
    public String job;
    public Person(String job)
    {
        this.job = job;
    }
    
    public void Work()
    {
        if(job.equals("Programmer"))
            System.out.println("코딩하다");
        else if(job.equals("Teacher"))
            System.out.println("수업을 하다.");    
    }
}

 

- SRP가 지켜진 경우

public abstract class Person {
    abstract public void Work();
}
 
 
public class Programmer extends Person {
    public void Work()
    {
        System.out.println("개발을 하다");
    }
}
 
public class Teacher extends Person{
    
    public void Work()
    {
        System.out.println("학생을 가르치다");
    }
}

 

위 두 코드 다 타 블로그를 참고했지만 직관적으로 차이를 볼 수 있다.

첫 번째 코드는 Programmer와 Teacher 두 직업을 책임지고 있다.

두 번째 코드는 클래스별로 각각의 직업을 책임지고 있다. -> SRP를 지키고 있다!

 

 

 

2. OCP(Open Closed Principle) : 개방 폐쇄 원칙

"기존의 코드를 변경하지 않고 기능을 수정하거나 추가할 수 있도록 설계해야 한다!"

- 요구사항이 변경되었을 때, 변경해야 되는 부분과 않아야 하는 부분을 구분해 변경해야 하는 부분을 유연하게 작성하는 것

- 이 부분을 위해 인터페이스 주로 사용한다.

 

Example)

- OCP 미적용

public class CarKey {
    CarA myCar;
    
    CarKey(CarA car) {
        myCar = car;
    }
    
    void open() { /* 문 열림 */ }
    void lock() { /* 문 닫힘 */ }
    void turnOn() { /* 시동 검 */}
}

 

- OCP 적용

public interface CarKey {
    void open();
    void lock();
    void turnOn();
}

 

첫 번째 코드에서 만약 새로운 차가 추가되면 똑같은 기능을 또 추가해야 한다.

두 번째 코드에서는 CarKey 인터페이스를 참조한다면 아무리 많은 차를 추가하더라도 똑같은 기능을 추가할 필요 없다.

 

 

 

3. LSP(Liskov Substitution Principle) : 리스 코프 치환 원칙

"자식 클래스는 부모 클래스에게 가능한 행위를 수행할 수 있어야 한다!"

- 서브 타입은 언제나 자신의 기반 타입으로 교체할 수 있어야 한다.

- 하위 클래스의 인스턴스는 상위 객체 참조 변수에 대입해 상위 클래스의 인스턴스 역할을 하는데 문제가 없어야 한다.

 

Example)

SRP의 예제를 가져오자.

 

현재 Person 클래스를 상속받는 Programmer와 TeacherPerson 역할이 가능하다.

public class Main {
    
    public static void main(String argsp[])
    {
        Person person1 = new Programmer();
        person1.Work();
        
        Person person2 = new Teacher();
        person2.Work();
    }
}

 

 

4. ISP(Interface Segregation Principle) : 인터페이스 분리 원칙

"한 클래스는 자신이 사용하지 않는 인터페이스는 구현하지 말아야 한다. 하나의 일반적인 인터페이스보다 여러 개의 구체적인 인터페이스가 낫다!"

- 자신이 사용하지 않는 기능에 영향을 받지 말아야 한다.

- 상위 클래스는 많을수록 좋고, 인터페이스는 적을수록 좋다.

 

Example)

- ISP 미적용

public class Programmer extends Person {
    public void Work()
    {
        System.out.println("개발을 하다");
    }
    public void Eating()
    {
        System.out.println("먹다");
    }
    public void Sleeping()
    {
        System.out.println("자다");
    }
}
 
public class Teacher extends Person{
    
    public void Work()
    {
        System.out.println("학생을 가르치다");
    }
    public void Eating()
    {
        System.out.println("먹다");
    }
    
    public void Sleeping()
    {
        System.out.println("자다");
    }
}

 

위 코드를 보면, 각 직업별로 중복되는 기능이 있다.

이 2개의 기능은 공통적으로 가지기 때문에 상위 클래스에서 구현해 하위 클래스에서 재사용하면 더 좋은 설계가 된다.

 

- ISP 적용

public abstract class Person {
    
    abstract public void Work();
    
    public void Eating()
    {
        System.out.println("먹다");
    }
    
    public void Sleeping()
    {
        System.out.println("자다");
    }
}

이처럼 상위 클래스에서 공통 부분을 구현하고(풍부할수록 좋다), 하위클래스가 따로 구현할 수밖에 없는 메서드구현을 강요하도록 한다.(인터페이스가 작을수록 좋다.)

 

 

 

5. DIP(Dependency Inversion Principle) : 의존 역전 원칙

"의존 관계를 맺을 때, 변화하기 쉬운 것보다 변화하기 어려운 것에 의존해야 한다!"

- 자주 변경이 되는 클래스에 대해서 의존하지 말아라.

- 의존관계를 맺을 때, 구체적인 클래스보다 인터페이스나 추상 클래스와 관계를 맺어라.

 

* 변화하기 쉬운 것 : 구체적인 것

* 변화하기 어려운 것 : 추상적인 것

 

Example)

 

만약 사람이 운동화를 신는다고 가정하면, 샌들을 신어야 할 때 변경되어야 한다.

하지만, 위처럼 추상화된 '신발' 인터페이스에 의존한다면 샌들을 신든 운동화를 신든 사람은 영향을 받지 않는다.

 

 

 

출처

https://landroid.tistory.com/8

https://ozofweird.tistory.com/entry/Java-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-5%EB%8C%80-%EC%9B%90%EC%B9%99-SOLID

https://lktprogrammer.tistory.com/38

반응형