모바일 앱 개발/확장가능한 아키텍처

[1부-코드레벨 아키텍처] 01. 아키텍처와 Composition

도툐리 2023. 1. 18. 02:15

compoistion을 잘 할 줄 알아야 어떤 아키텍처를 사용하든 massive에서 벗어날 수 있음.

compoistion을 활용해서 객체를 잘게 쪼개고 로직을 분산시킨 다음에 이걸 다시 합쳐서 내가 원하는 기능을 만들어낼 수 있어야 함.

 

작은 객체로 이루어진 코드들은 재사용성이 굉장히 좋음. + 유지보수 용이

+ 테스트 용이 (public API도 적고, parameter도 적기 때문에 테스트해야하는 조합의 순열이 적기 때문)

상속은 코드의 가장 강한 결합의 형태이기 때문에 상속보다는 가능하다면 기능확장 시 composition(결합)을 사용하는것이 보다 현명하다.

 

상속은 필요할땐 유용하지만 때때로 유연성이 떨어짐. 우리가 원치 않는 기능까지 딸려올 수 있음. 그러다보면 부모의 행동을 거부하기 위해서 빈 over-ride를 만든다던지 super를 호출하지 않고 기능을 만든다던지 하는 방식으로 부모의 행위를 거부하고 덮어씌우게 되는데, 이는 리스코프 원칙에 위배됨. 리스코프 원칙에 위배되는 코딩을 하게 되면 해당 코드 작성자가 예상치 못한 동작을 마주하게 될 확률이 높음.

(원칙들을 모두 100% 따라야 하는건 아니지만, 해당 원칙을 어겼을때 발생할 수 있는 부작용들을 이해하고, 그를 굉장히 제한적으로 쓸 필요는 있다.)

 

그래서 코드를 재사용해야할때, 우리가 바로 상속부터 사용한다면 요구사항이 변화할때 민첩하게 대응하기가 어려워질 수 있다는것. 기억 

 

(ex) 아래와 같이 짠다면, 중장기적인 관점에서는 A와 B가 너무 끈끈하게 묶여있기 때문에 유지보수가 힘들 수 있음.

같은 상황에서 composition을 활용한다면, 아래와 같이 짤 수 있음.

-> 작은 객체 A,B를 조립해 만든 C

 

보통 상속은 white box, composition은 black box라고 함. 

상속할 경우 B는 A의 모든걸 알고 있기 때문.

 

하나의 객체가 너무 많은걸 알고있거나 너무 많은 로직과 데이터를 가지고 있다면 아 뭔가 잘못됐구나 생각할 필요가 있음.

더 작고 더 적게 아는 객체를 만드는게 유지보수 관점에서는 훨씬 유리함. 코드 가독성도 좋아지고.

 

함수에도 compoisition을 적용해볼 수 있는데,

map은 Optional, Sequence, Result, Publisher 이렇게 네가지 타입에 정의되어있는데, 넷의 공통점은 아래와 같음.

type을 바꿔줘야할때 map 사용 가능
map vs flat map
결국 앱에서 일어나는 일련의 과정들은 다 타입을 전환시켜주는 함수들의 모음이라고 볼 수 있음.

위 과정은 아래와 같이 map과 flat map으로 표현해줄 수 있음

map과 flatmap을 활용해 함수 조립!!

 

reducer는 state change 해주는 애. 앱이 커질수록 리듀서가 담당해야하는 state값들이 많아지고 로직도 복잡해질꺼임.

그렇기 때문에 여러개의 작은 리듀서들을 조합해 하나의 리듀서를 만드는 등 composition 을 적극 활용할 수 있음.

=> 로직 분산 후 다시 조립

아무리 복잡한 화면이나 큰 앱이라 하더라도 200줄 정도 되는 작은 객체들로 조립이 되어있다면 개발자 입장에서 유지보수가 굉장히 용이하겠지

요렇게 트리구조로 되어있음

 

=> 앱은 처음엔 작게 시작하지만 점점 복잡해지고 화면도 많아지면서 코드 양또한 방대해짐. 

compoistion이 가능한 아키텍처는 앱이 아무리 커지고 복잡해져도 파고 파고 들어가보면 맨 마지막에는 이해하기 쉬운 작은 요소들로 분해가 됨. 그렇기 때문에 코드도 이해하기 쉽고, 원하는 코드를 찾기도 훨씬 용이해짐.

 

비대해진 뷰컨트롤러나 너무 많은 일을 하는 비대한 객체 없이도 복잡한 화면과 복잡한 앱을 만들 수 있게 되는 것!!

 

 

 


느낀점:

아니.. 예시코드가 다 스위프트니까 은근 알아듣기가 어렵다 ㅠ

언어 다 거기서 거기고 비슷할꺼라 생각해서 별 생각없이 들어야겠다고 생각한건데.. ㅠ_ 하쒸