5/30 SOLID

박세현·2024년 5월 30일
0

3차 프로젝트

목록 보기
8/14
post-thumbnail

SOLID

  • 객체 지향 설계 원칙

S : 단일 책임 원칙

  • 단일 책임 원칙(Single Responsibility Principle)
  • 하나의 클래스는 하나의 책임을 가짐


O : 개방 폐쇄 원칙

  • 개방 폐쇄 원칙(Open Closed Principle)
  • 확장에는 열려 있고, 변화에는 닫혀 있음

  • 디자인패턴 : 전략패턴
  • 상속은 확장에 불리
    • 필요없는 메서드도 상속을 받아야 됨
    • 부모클래스 1,2,3번에 있는 메서드 모두 사용하고 싶은데 상속은 부모가 한개만 있을 수 있으니까 확장에 불리
      -> 인터페이스가 설계에 더 적합 : 인터페이스 분리원칙
  • 구성이 확장에 유리
  • 직접 구성 객체를 생성❌ -> 통제 불가
  • 통제를 위해서 구성 객체의 주입 개방 -> 생성자 매개변수(의존 관계), Setter 메서드(연관관계)를 통해서
    • 생성자 매개변수(의존 관계) : 의존성들이 투입되지 않으면 해당 클래스가 객체가 될 수 없음 = 의존성이 무조건 있어야 함
    • Setter 메서드(연관관계)를 통해서 : 해당 클래스가 객체가 되고나서 주입해도 됨 = 없어도 된다!
  • 의존성
    • 클래스가 필요로 하는 객체
    • 이 클래스가 객체가 되었을 때 이 기능을 하기 위해서 필요로 하는 구성부품
    • 의존성들은 직접 객체로 생성하기 보단 주입 받는 구조 즉 열린구조가 되어야 통제가능
      = 개방

예시) 상속은 확장에 불리

ㄴ Bird추상클래스 생성
ㄴ 추상메서드 fly(), speak() 2개 정의

ㄴ Eagle클래스가 Bird추상클래스 상속받음
ㄴ 추상메서드 fly(), speak() 2개 완전 구현함

ㄴ Chicken클래스가 Bird추상클래스 상속받음
ㄴ 음? 치킨은 못 날라가는데 Bird추상클래스라는 추상클래스 상속받아서 무조건 구현해야 하넹
= 상속 시 필요없는 메서드도 상속을 받게 됨
= 상속은 확장에 불리하다
-> 인터페이스가 설계에 더 적합 : 인터페이스 분리 원칙

ㄴ 인터페이스 분리 원칙 : 역할별로 인터페이스를 분리



예시) 인터페이스 분리원칙

ㄴ 인터페이스 분리 원칙 : 역할별로 인터페이스를 분리

ㄴ 상속이 아닌 인터페이스 implements로 바꿈

ㄴ 상속일 땐ㄴ fly()메서드(필요없는 메서드)도 구현했어야 했는데
ㄴ 인터페이스 분리원칙을 사용함으로서 필요없는 메서드 구현안해도 됨



예시) 확장은 상속은 불리

ㄴ 컴퓨터 클래스 정의

ㄴ 데스크탑이 컴퓨터 상속받음

ㄴ 태블릿이 컴퓨터 클래스 상속받음
ㄴ 태블릿은 터치스크린이랑 바디만 필요한데 필요없는 키보드, 마우스, 모니터 클래스도 딸려옴

ㄴ 컴퓨터(부모클래스)에 터치스크린 추가함
ㄴ 이러면 데스크탑이 반대로 필요없는 터치스크린을 상속받게 됨
-> 상속 : 불필요한 자원들을 포함하여 확장하게 된다(유연성이 떨어진다)
-> 상속보단 구성의 방식을 쓰는 것이 유연하다

예시) 상속보단 구성의 방식을 쓰는 것이 유연하다

ㄴ 키보드

ㄴ 모니터

ㄴ 터치스크린

ㄴ 바디

ㄴ 마우스
-> 키보드, 모니터, 터치스크린, 바디, 마우스 모두 구성부품

ㄴ 구성의 방식 적용
-> 필요한 부분만 가져다 쓸 수 있음

ㄴ 구성의 방식 적용
-> 필요한 부분만 가져다 쓸 수 있음



예시) 리스코프 치환원칙

모니터의 기능이 업그레이드 되서 모니터 구성부품을 바꿔주려고 함
근데 기존의 틀을 유지하면서 바꾸고 싶음

ㄴ 업그레이드모니터 클래스 생성

ㄴ 업그레이드모니터 클래스가 모니터를 상속받음

ㄴ 다형성을 이용하면 기존의 틀을 유지하면서 바꿀 수 있음
-> 근데 이것도 문제가 있음
-> 만약 데스크탑이 100개가 있으면 100개의 메서드를 다 수정해 줘야 함
-> 통제가 안됨 그럼 통제를 하려면? (통제 = 직접 수정 가능하다)
-> 주입의 방식
: 필요한 구성부품들을 직접 생성하는게 아니라 확장할 수 있게 열어놓자(개방)

  • 생성자함수의 매개변수(의존관계)
  • setter메서드(연관관계)


예시) 생성자 매개변수

ㄴ 생성자 매개변수 : 직접 객체를 생성하지 않고 외부에서 주입받아서 객체 생성(개방, 통제가 가능하도록 하기 위해 개방하는 것)
ㄴ 의존성 : 이 클래스가 필요로 하는 객체
ㄴ 모니터, 바디, 키보드, 마우스각 객체가 되지 않으면 데스크탑도 객체가 될 수 없음
-> 근데 이 방식도 데스크탑에 부품을 추가할 시 데스크탑 클래스가 100개 이면 100개의 메서드를 이렇게 다 수정해줘야 함
-> 하나의 클래스에서 객체를 조립하자 = 하나의 클래스가 객체를 통제하자
-> 다만 통제하기 위해선 열려있어야 함

ㄴ 컴퓨터어셈블러 클래스 생성(객체 조립기)

ㄴ 이미 완성된 데스크탑 객체를 생성해줌

ㄴ 매번 new해서 객체 생성하지 않고 항상 도립되어 있는 완성된 객체를 불러올 수 있음



예시) 객체직접생성 ↔ 객체조립기

내가 데스크탑 클래스에 그래픽카드라는 객체를 추가하려고함

  • 기존방식

-> 데스크탑을 객체로 생성하고 있는 모든 클래스의 코드를 다 바꿔줘야함

  • 조립기

-> 객체조립기클래스에서 그래픽카드 객체를 데스크탑 생성자 매개변수에 추가만 해주면 데스크탑객체를 사용하고 있는 모든클래스가 알아서 바뀐 데스크탑 객체를 적용하게 됨



예시) 폐쇄 원칙

ㄴ 바디클래스에 run()메서드를 정의함

ㄴ run()메서드 안에 body.run()메서드 정의함 왜?
-> 데스크탑은 body.run()메서드의 변화에 영향을 받음
-> 직접 body.run()을 호출하면 통제불가
-> 보통 통제를 하기위해선 메서드 안에 정의 like 정보은닉 = 메서드 안에 있어야 통제가 가능하다



예시) 확장은 개방 변화는 폐쇄

ㄴ 확자은 개방

ㄴ 변경은 폐쇄



L : 리스코프 치환 원칙

  • 리스코프 치환 원칙 (Liskov Subsititution Principle)
  • 서브타입은 언제나 기반 타입으로 교체할수 있음(다형성)
  • 하위 클래스 자료형 -> 상위 클래스의 자료형


I : 인터페이스 분리 원칙

  • 인터페이스 분리 원칙(Interface Segregation Principle)
  • 하나의 인터페이스에 설계 항목을 너무 많이 X, 역할별로 인터페이스를 분리
    예) java.time 패키지의 핵심 클래스, LocalDateTime

예시) java.time 패키지의 핵심 클래스, LocalDateTime

ㄴ 역할별로 분리도어 있는 모습



D : 의존 역전 원칙

  • 의존 역전 원칙(Dependency Inversion Principle)
  • 특정 대상을 직접 참조하기 보다는 그 대상의 상위 요소인 추상클래스 또는 인터페이스로 참조
    예) 컬렉션 프레임워크
    ArrayList<String> items = new ArrayList<>(); (X)
    -> 향 후 변경가능성이 있을 때 유연하지 못함
    List<String> items = new ArrayList<>(); (O)
    -> 향 후 변경가능성이 있을 때 유연함
    -> 향 후 ArrayList말고 다른 걸로 바꿀 때(LinkedList...) 호환이 됨
profile
귤귤

0개의 댓글

관련 채용 정보