-
[클린코드] 추상화, 관심사의 분리,의존성주입 (Java script version)Java Script & Type Script 2023. 7. 27. 16:01728x90
우리회사 개발팀분들과 일주일에 한번씩 클린코드를 읽고 관련해서 아이디어와 코드를 공유하는 스터디를 하고있다.
클린코드의 예시코드는 모두 자바라서 (자알못) 따로 검색해보고 자바스크립트코드를 쳐보지 않으면 이해가 어렵다 ㅠㅠ!!
이 챕터는 "시스템" 챕터!
추상화
- 컴퓨터 과학에서 추상화는
복잡한 자료, 모듈, 시스템 등으로부터 핵심적인 개념 또는 기능을 간추려 내는 것
을 말한다. - 복잡하고 불필요한 세부 사항을 숨겨 코드를 더 간단하고 읽기 쉽고 유지 관리하기 쉽게 만드는 프로세스
- 추상화는 구체적인 사물들간의 공통점을 취하고 차이점을 버리는
일반화
를 사용하거나, 중요한 부분을 강조하기 위해 불필요한 세부 사항을 제거함으로써 단순하게 만듭니다. 결국 핵심은 불필요한 코드를 제거하고 중요한 부분을 살리는 것. - 만약, 제가 은행 관련 애플리케이션을 만든다고 가정해 보겠습니다. 은행을 이용하는 고객의 정보가 필요할텐데, 고객의 정보라고 하면 이름, 주소, 휴대폰 번호, 주소 등이 있을 수 있습니다. 그런데, 사실 정보라는 범위가 모호하므로 위의 정보 외에도 좋아하는 음식, 취미, 특기 등까지도 포함할 수 있습니다. 다만, 은행 애플리케이션에서의 고객 정보로 좋아하는 음식, 취미, 특기는 필요하지 않습니다. 그래서 이러한 불필요한 정보를 제거함으로써 중요한 정보만 남기는 것 자체도 추상화라고 할 수 있습니다.
- JavaScript에서는 맵, 축소, 필터와 같은 고차 함수를 활용하여 일반적인 연산을 추상화하고 코드를 더욱 간소화함으로써 한 단계 더 나아갈 수 있다.
- 캡슐화란 클래스 안에 서로 연관있는 속성과 기능들을 하나의 캡슐(capsule)로 만들어 데이터를 외부로부터 보호하는 것을 말합니다. 즉 서로 관련 있는 데이터와 이를 처리할 수 있는 기능들을 한곳에 모아 관리하는 것입니다.
// 추상화 전 const lstOfStrings = ['6', '7', '8']; let sum = 0; for (let i = 0; i < lstOfStrings.length; i++) { sum += parseInt(lstOfStrings[i]); } console.log(sum); // Output: 21
function sumList(lst) { const nums = lst.map(str => parseInt(str)); // 맵과 화살표 함수를 사용하여 각 문자열을 정수로 변환 const sum = nums.reduce((acc, num) => acc + num); // 합계 함수를 reduce와 숫자 목록을 더하는 또 다른 화살표 함수로 대체 return sum; } const lstOfStrings = ['6', '7', '8']; const result = sumList(lstOfStrings); console.log(result); // Output: 21 // map을 사용하여 각 문자열을 정수로 변환하고 // reduce를 통하여 정수의 배열을 합산함으로써 코드를 단 몇 줄로 줄일 수 있다.
관심사의 분리
- 각각의 관심사에 따라 코드를 분리하는 기법
- 코드가 하나의 관심사만 신경쓰도록 분리하는 것
- 특정한 변화에 대응하기 위해 읽고 이해하고 수정해야 하는 코드의 단위를 줄일 수 있어 유지 보수에 용이해진다.
- 하나의 코드가 하나의 기능을 담담하기에 여러 역할이 혼재된 코드보다 단위별로 재사용하기 쉬워진다.
- 코드의 기능 테스트 또한 쉬워진다.
- 관심사의 분리가 잘 된 소프트웨어는 낮은 결합도와 높은 응집도란 특징이 나타난다.
- 낮은 결합도 (Loose Coupling) : 코드가 얽혀있지 않고 관심사에 따라 독립적으로 잘 분리되어 있다.
- 높은 응집도 (High Cohesive) : 동일한 목적(관심사)를 가진 코드끼리 잘 모여있다.
의존성 주입
의존성 주입의 정의: 클래스간 의존성을 클래스 외부에서 주입하는 것
// 의존성 주입 x //users-service.js const User = require('./User'); const UsersRepository = require('./users-repository'); async function getUsers() { return UsersRepository.findAll(); } async function addUser(userData) { const user = new User(userData); return UsersRepository.addUser(user); } module.exports = { getUsers, addUser }
해당 코드의 문제는 ./users-repository에서 import해왔기 떄문에 다른 곳에서 이들을 사용할 때 유동적으로 사용하지 못하고 결과값이 정해진다.
다른 곳에서 userRepository의 내용말고 userDB에서 가져오고 싶어도 사용할 수 없는 것이다.
const User = require('./User'); function UsersService(usersRepository) { // check here async function getUsers() { return usersRepository.findAll(); } async function addUser(userData) { const user = new User(userData); return usersRepository.addUser(user); } return { getUsers, addUser }; } module.exports = UsersService
이렇게 코드를 고치면 다른 곳에서 UserService.getUsers(아무거나) 를 통해 다양한 값을 줘
user.js, userRepository.js → UserService(내부는 정해져 있음 무조건 userRepo)였던 부분을
user.js → UserService(userDb)으로 바꿀 수 있게 되는 것이다.
728x90'Java Script & Type Script' 카테고리의 다른 글
[React] 디자인패턴 Custom hook Pattern-UI와 비즈니스로직의 분리에 대하여 (0) 2024.01.20 [React] Tanstack react-query 데이터 리패칭의 네가지 방법 (1) 2023.12.28 [자료구조] Map과 Set (0) 2023.07.10 [JS] 내가 몰랐던 ES6 최신문법 (0) 2023.07.10 [React] Recoil 설정과 대표 기능 소개 (0) 2023.04.29 - 컴퓨터 과학에서 추상화는