211203 - 프레임워크

빡새·2025년 3월 2일

어떤 클래스를 만들어서 쓰고 있었다.

근데 자주 나오는 로직, 절차가 보인다.
그런 코드는 나올 때마다 새로 쓰면 귀찮다.
아래 쪽에 메소드를 따로 만들어서 그 로직만 담는다.
그리고 위에서 다른 메소드를 짤 때,
그 로직이 필요할 때마다 꺼내서 쓴다.

자, 이제 규모를 키워 보자.
프로젝트가 크면 클수록 겹치는 코드도 엄청 많아진다.
자주 쓰는 로직이 한두 개가 아니다.
앞에서 그런 로직들을 모아서 따로 메소드를 만든다고 했다.
그런데 그렇게 만든 메소드들이 한두 개가 아니니,
그런 메소드들만 모아서 아예 클래스를 따로 만들 수도 있다.
그러니까, 파일을 아예 따로 만드는 것이다.
그리고 클래스들마다 그 파일을 불러온 뒤에,
쓰고 싶은 내용 이어서 쓰도록 한다.

첫째로, 클래스가 단순해지고 가벼워진다.
자주 쓰는 내용임에도 파일이나 클래스마다 새로 쓴다면?
자주 쓰는 부분은 어차피 다 똑같은데,
괜히 코드만 길어져 보이고 복잡해 보이고 파일도 무거워진다.
근데 중복되는 내용은 뽑아서 따로 파일을 만든다면?
그럼 중복되는 부분 전체가 클래스에서 싹 사라지는 거니까
그만큼 코드도 짧아지고 파일이 가벼워진다.

둘째로, 수정이 용이해진다.
파일이 200개 있는데, 200개마다 자주 쓰는 내용을 새로 썼다면?
기능 뭐 하나 바뀌면 200개 파일마다 다 바꿔야 한다.
근데 자주 쓰는 로직이나 코드는 한 파일에 모아서 만들고,
나머지 200개 파일은 그 한 파일을 불러다 쓰고 있다면?
파일 하나만 바꿔도 그 파일을 불러다 쓰는 나머지 200개 파일은 저절로 수정된다.
규모가 커질수록 이렇게, '별도 메소드나 클래스를 따로 만들어서 모아두는 구조'의 장점도 커진다.

자, 규모를 키웠으니까,
이번에는 세분화 해 보자.
예를 들어서, 컨트롤러, 모델, 뷰, 각각 자주 쓰는 로직이 다르다.
컨트롤러에서는 A처리도 하고, B 처리도 하고, C처리도 한다.
모델에서는 D처리도 하고, E처리도 하지만, C처리도 한다.
C가 겹친다.
뷰에서도, 어디는 겹치고 어디는 안 겹쳐.
이럴 땐 어떻게 해야 좋을까?
A, B, C, D, E, F ... 다 모아 놓은 파일을 만들어 두고,
모든 클래스가 그 파일 불러다 쓰게 만들면?
컨트롤러에서는 쓰지 않는 D, E, F를 굳이 불러야 하고,
뷰에서는 쓰지 않는 A, B, C를 굳이 불러야 한다.
좀 무겁지 않을까?
컨트롤러 만들 때는 딱 컨트롤러에서 자주 쓰는 파일만 부르고,
모델에서도 모델에서만 자주 쓰는 거만 최소한으로 딱 부르고,
뷰도 그렇게 하고, 그러면 좀 가벼울 텐데 말이다.
어떻게 방법이 없을까?

파일이나 클래스를 좀 세분화 해서 나누면 되지 않을까?

컨트롤러가 자주 쓰는 코드,
컨트롤러와 모델이 자주 쓰는 코드,
컨트롤러와 모델은 자주 쓰지만 뷰에서는 쓰지 않는 코드,
컨트롤러든 모델이든 뷰든 어디서든 자주 쓰는 코드, 다 따로 있다는 말이다.
어디는 교집합이고 어디는 차집합이나 여집합도 있다는 것이다.
그럼 각각 집합별로 파일을 하나씩 만들어 주면 어떨까.
복잡해 보이기도 하고 번거롭거나 귀찮아 보이겠지만,
앞에서 보았듯이, 규모가 커질수록 효율이 어마어마하게 차이날 것이다.

컨트롤러 작업할 때 자주 쓰는 로직이나 절차만 모아서 클래스 따로 하나 만들어 두고,
모델 처리할 때 자주 쓰는 코드도 따로 모아 두고,
뷰 다룰 때 자주 쓰는 코드도 따로 모으고,
덧붙여서, 어디서든 공통적으로 자주 쓰는 코드나 로직도 따로 모아서 파일이나 클래스를 만들고.
이렇게 하면 가볍지 않을까?
컨트롤러 클래스를 만들 때는 자주 쓰는 코드만 모아 둔 파일을 불러다 쓰고,
모델 클래스 만들 때는 모델 다룰 때 자주 쓰는 로직만 모아 뒀던 파일 불러다 쓰고,
뷰도 그렇게 하고,
그리고 자주 쓰는 파일들은 각각 공통적으로 자주 쓰는 코드 모아 놓은 걸 부르도록 해 놓는다.
한 마디로 역 피라미드 구조가 된다.
수정도 더 용이해지고, 편하고 가벼워진다.

이게 바로 프레임워크다.

전체적인 구조, 틀, 프레임, 골격을 미리 짜 두는 것이다.
그래서, 어떤 프레임워크를 쓴다 하면,
컨트롤러 만들 때는 뭐를 부모 클래스로 이어서 받아야 하고,
모델 클래스 만들 때는 저쪽을 부모 클래스로 받고,
그런 게 이미 정해져 있다.
자주 쓰는 로직도 자기네가 만들어 둔 메소드가 따로 있다.
그 함수나 클래스들의 이름, 부르는 방법, 파라미터, 등등을
걔네들이 정해 놓은 룰에 따라야 한다.

그럼 라이브러리는 뭘까?

이런 경우가 있다.
어떤 로직이나 메소드가 있다.
컨트롤러에서 쓰기는 쓴다.
근데 자주 쓰지는 않는다.
애매하다.
컨트롤러라고 하면 거의 모든 컨트롤러가 공통적으로 쓰는 기능이 있을 것이다.
그런 건 파일을 따로 만들어서 컨트롤러를 만들 때마다 불러다 쓰도록 하면 된다.
그런데 그렇다고 그 파일에 이런저런 잡다한 기능들을 다 넣어두면?
자주 쓰지 않는 로직이나, 어쩌다 한 번씩 쓰는 메소드들까지 다 때려 넣어두면?
컨트롤러 만들 때마다 그 파일을 불러다 써야 하는데,
당연히 다른 모든 컨트롤러들까지 같이 무거워지겠지.

같은 컨트롤러 클래스라고 해도, 이쪽 클래스에서는 자주 쓰겠지만,
저쪽 클래스에서는 아예 건드리지도 않는다.
클래스가 만들어질 때 그런 잡다한 기능들을 일단 다 불러다 놓고 시작하면?
모든 컨트롤러 클래스들이 무거워진다.
그래서, 자주 쓰기는 하는데, 공통 클래스에 넣기는 좀 그렇고,
이쪽 메소드에서는 자주 쓰는데, 저쪽 메소드에서는 잘 안 쓰고,
그런 애매한 것들은 차라리 필요할 때만 불러다 쓰도록 한다.
자주 쓰는 로직이니까 일단 미리 만들어 두기는 하겠다.
그렇다고 컨트롤러 전체에 공용으로 올릴 정도로 범용으로 쓰지는 않으므로,
메소드에 따라서 필요한 경우에만 불러다 쓰도록 하자.
그런 게 바로 라이브러리다.

결국, 얼마나 범용성 있는 로직, 절차, 코드인가,
이걸 프로젝트 전체 단위로 올려둘 것인가,
컨트롤러단 전체에 올려놓고 쓸 것인가,
딱 이 컨트롤러 클래스에서만 불러다 쓸 것인가,
아니면 이 메소드에서만 전체적으로 쓸 것인가,
또는 이 로직 블록에서만 쓸 것인가,
전체적인 구조를 설계할 때 고려해야 하는 아주 중요한 요소다.
변수를 선언하는 것도,
함수를 미리 만들어 두는 것도,
그 함수를 모아둔 파일을 만드는 것도,
그 파일을 어디에서 불러다 쓸지도,
이런 요소를 고려해서 설계하는 것이다.
중복을 최소화 하기 위해 파일, 클래스, 메소드, 로직, 변수 등을 따로 구비해 두고,
그러면서도 불피요한 코드들까지 따라오지는 않도록 적당히 쪼개서 들고 다니는 것.

-211203

0개의 댓글