SOLID

나이든별 / Oldstar·2022년 5월 29일
0

Think about Keywords

목록 보기
21/37

공부한 것

  • SOLID

복기

  • SRP(단일 책임 원칙)
    • 작성된 객체는 하나의 기능만 가지며, 클래스가 제공하는 모든 서비스는 그 하나의 기능을 수행하는 데 집중되어 있어야 한다.
    • 사실 어느 정도는 귀에 걸면 귀걸이 코에 걸면 코걸이다.
    • 대표적으로 애플 MVC의 뷰 컨트롤러는, 많은 일을 한다. 뷰도 만들고, 데이터도 렌더링 및 변환하고 등등
    • 기본 프로퍼티를 3개 이상 사용하지 않도록 화면을 구성한다, 메서드의 갯수가 몇 개 이상이거나 하면 클래스를 분리한다, 메서드의 줄 수가 7줄 이상이면 분리한다… 등. 추가적인 규칙을 정해 준다.
    • 이를 통해 타입이 조금씩 쪼개지면서, 역할이 좀 더 구체적으로 변한다.
    • 책임은 변경의 이유이다.
    • 변경을 위한 이유가 같은 것으로 모였을 때, 즉 응집도가 높을 때(결합도가 낮을 때) 수정에 유리하다.
    • 예를 들면 하나의 타입에 하나의 역할을 하는 코드가 다 모여 있는 것.
    • MVVM도 어떻게 보면, 이런 뷰 컨트롤러의 부담을 덜어주기 위해 나온 것일수도?! 뚱뚱한 뷰 컨트롤러의 역할과 책임을 덜어 주고 싶다면 사용할 수 있겠다.
    • 커밋할 때 여러 개의 파일을 건드려 놓고 고민하는 게 낮은 응집도.
    • 목적이 같고 코드가 중복되는지, 아니면 우연히 코드가 중복되는지, 잘 생각해봐야 한다.
    • 구기종목 계산기를 같이 썼다가, 야구게임의 스코어가 농구게임에 영향을 줄 수 있다.. 구기종목 계산기를 변경할 필요가 있을 때, 그 이유가 너무 많아진다. 야구게임에 변동이 생겨도 변경해야 하고, 농구게임에 변동이 생겨도 변경해야 하고..
  • OCP(개방-폐쇄 원칙)
    • 확장(기능 추가 등)에는 열려 있고, 변경(기존 코드의 수정 - 다른 코드에 연결이 되지 않도록)에는 닫히도록.
    • 확장을 할 때는 기존 코드를 최대한 건드리지 말자.
    • 기존의 코드를 수정할 때 연쇄적인 수정을 하지 않도록.
    • 변경이 전염되지 않으면서 새로운 기능 추가 가능 - 기존 코드의 수정이 필요없으니 재검증 없이 소프트웨어를 키워나갈 수 있다(이상)
    • 도형이라는 타입이 있고, 삼각형 사각형 오각형 등이 있다고 생각해보자. 둘레라는 변수가 있고.
    • 이러한 경우 열거형은 케이스(새로운 도형)를 추가하면서 사이드 이펙트가 너무 많이 발생한다.
    • 하지만 프로토콜의 경우 기능(프로퍼티 등)을 추가할 때, 프로토콜을 준수한 모든 타입을 수정해야 한다.
    • 은탄은 없다는 걸 기억하게 되겠다. 그때그때 맞는 방법으로 구현하자.
  • LSP(리스코프 치환 원칙)
    • 자식 클래스는 부모 클래스의 기능을 완벽히 수행할 수 있어야 한다.
    • 자바에서는 실제로 inherit보다 extend라는 말을 쓴다?!
    • 직사각형을 상속한 정사각형이라고 했을 때, 정사각형은 변의 길이를 무조건 같게 동기화해준다. 이 때, 정사각형은 직사각형의 모든 특성을 계승받지 못했기 때문에(변의 길이가 다른 경우를 포괄하지 못하기 때문에) 리스코프 치환 원칙에 위배된다.
    • 타입을 설계할 때, 현실의 관념이 무조건 적용되는 것이 아니라는 거다..
    • UIKit에서 보면, UIView를 상속받은 레이블 텍스트필드 슬라이더.. 등의 친구들이 있다. 뷰는 높이와 너비를 바꿀 수 있는데, 상속받은 친구들 중에서는 높이나 너비를 조정할 수 없는 놈도 있다. 이런 것도 위반 사례. 원칙이 우선인가 가치가 우선인가?
    • 특히나 이 원칙을 지키는 것은, 현실세계를 그대로 반영하지 않을 수 있다.
  • ISP(인터페이스 분리 법칙)
    • 클라이언트가 불필요한(자신이 이용하지 않는) 인터페이스에 의존하지 말아야 한다.
    • 큰 인터페이스를 작은 인터페이스들로 분리하여, 사용자가 이용할 인터페이스를 취사선택해야 한다.
      • movable 프로토콜에 movejump가 있다면, 근데 달팽이는 점프를 안 쓰는데도, 구현해야 하잖아??
      • 그래서 jumpable을 따로 분리해주라는 것이다.
      • typealias movable = transferable & jumpable
    • 어느 정도까지의 선에서 이걸 구분해야 할까 고민해봐야 한다. 굉장히 추상적인 느낌.
  • DIP(의존성 역전 원칙)
    • 상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안 되며, 구체적인 사항은 추상화에 의존해야 한다.
    • 구체적인 것은 잘 변하고, 추상적인 것은 잘 안 변한다.
    • 프레임워크나 라이브러리는 우리의 앱에 대해 몰라야 하고, 몰라도 잘 돌아가야 한다.
    • UITextView는 우리의 뷰 컨트롤러에 대해 알아야 하지만(우리의 앱의 자료형이니까), 사실 그렇지 않잖아 말이 안 되잖아?
    • 하지만 Delegate을 미리 정의해 두면, 서로 그것만 참조해서 통신할 수 있다.
    • 컴퓨터가 마우스 A만을 원할 때, 다른 마우스도 쓸 수 있게 하려면, USB라는 범용 프로토콜을 사용하면 되지 않을까? 컴퓨터와 마우스 모두 USB라는 프로토콜을 따르면 서로 연결될 수 있겠지. 여기서 USB가 상위 모듈이 되는 것이다.
    • 이렇게 하면 근데 또 유연함을 지키기 위해 단순함을 희생하게 될 수 있겠다. 딱 봐도 코드의 양이 엄청 늘어났다.
    • 죽을 때까지 마우스A만 쓸 거라면, 단순함을 챙기는 게 좋을 수도 있겠다. 역시 은탄은 없다.

고민한 점 및 생각해본 점

  • 가장 인상적인 말은 '은탄은 없다'라는 것. 마스터키는 없다는 뜻이다. 그때그때 pros와 cons를 따져서 필요한 것을 취해야 한다.
  • 다만 매우매우 거칠게 요약하면, 코드를 짤 때 항상 적절한 모듈화를 염두에 두면 무의식적으로 많은 부분을 지킬 수 있지 않을까 한다.
  • 또 하나. 이전에 미숙할 때 짠 작은 앱의 코드도, 사실 틀린 건 없다는 것을 좀 체감했다. 그때그때 사용할 수 있고 필요했던 방법을 사용했을 뿐..

참조

https://www.nextree.co.kr/p6960/

profile
함께 나아가고자 하는 사람

0개의 댓글