일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 코틀린
- javascript async
- 코틀린 클래스
- jpa 플러쉬
- Flutter
- gradle 모듈 프로젝트
- 스프링부트
- 준영속상태
- javascript api 호출
- ja async
- jpa 플러시
- javascript async await
- jpa 영속성
- javascript fetch
- JPA플러시
- JPA
- JPA준영속 상태
- js await
- springboot gradle 모듈 프로젝트
- js api 호출
- springboot 모듈
- 코프링
- js async await
- spring 모듈 프로젝트
- JPA플러쉬
- spring gradle 모듈
- JavaScript
- JS
- js fetch
- jpa준영속
- Today
- Total
매일 한줄 코딩
3주차 - 추상화란? 어떨때 추상화를 하면 좋을까? 본문
추상화란?
의도, 프로세스, 특징, 속성 등을 개념적으로 표현한 것을 말한다 → 컨셉화
💡
예제 1)
<div class=”red”> ... </div>
<div class=”warning”> ... </div>
예제 2)
plus(100);
deposit(100);
예제 1 에서 div 태그에 class 속성을 주었다.
차이는 명칭이 red와 warning 이다.
- red는 경고하기위해 빨간색으로 표시하겠다라는 표현의 정도 → How (어떻게)
- warning은 경고라는 의도를 표현하는 정도다. → What (무엇을)
예제 2 에서 plus함수와 deposit함수를 호출하는 내용이다.
각각 100이라는 값을 함께 넘겨주고 있다.
- plus함수는 받은 인자인 100을 더해주겠다는 것으로 보인다 → How (어떻게)
- deposit함수는 받은 100을 예금해준다는 것으로 보인다 → What (무엇을)
다시말해서, 추상화란 구현을 감추고 의도를 들어내는 것이라고 볼 수 있다.
코드로 예를 들어보면,
...
//회원가입 regist 메소드.
regist(Request request) {
...
...
sendMail();
}
처음에 회원가입하는 메소드를 호출하고 마지막에 회원가입이 잘 되었다고 통보하는 sendMail(); 이라는 메일을 발송해주는 메서드가 있는 형태이다.
이때에, 메일뿐만 아니라 SNS로도 발송하는 기능과, 카카오톡 알리미로도 발송하는 기능도 넣어달라는 요청을 받는다면...
...
//회원가입 regist 메소드.
regist(Request request) {
...
...
if ("mail".equals(request.sendType)) {
sendMail();
} else if ("SNS".equals(request.sendType)) {
sendSns();
} else if ("KATALK".equals(request.sendType)) {
sendKakao();
} else {
...
}
}
위와 같은 식으로 코딩을 하게 될 것이다.
하지만 추상화한다면 어떻게 될까?
일단 의도는 회원가입시에 통지를 하려는 의도로 mail이든, sns든, kakaotalk이든 각 의도는 통지의 의도를 갖고있는 공통점이있고 수단만 다른 형태인 것이니 통지되는 인터페이스를 만들고 각각의 구현부를 만들어서 호출하면 된다.
...
//회원가입 regist 메소드.
regist(Request request) {
...
...
send.notify(..);
}
위와 같이 만들어주면 된다.
이렇게 변경하게 되면, 추후에 다른 알림방법이 들어오더라도 regist를 직접 수정하지 않고, 인터페이스를 상속받는 부분만 구현부를 추가해주면 된다.
결론적으로 말하면..
처음엔 regist(); 내에 sendMail(); 하위기능을 사용하고, 그 하위 기능인 sendMail(); 이 직접 구현하였지만
요구사항이 추가되면서 공통화 된 부분(의도가 맞는 부분) 들이 생기게 되었다.
그래서, 인터페이스로 정의하여 처리하기로 한다.
그렇게 된다면 위와 같은 형태로 바뀐다.
이는, regist(); 는 interface를 사용하게되며, 각각 방법(sns, email, katalk.... 등) 은 interface를 상속받아서 각각 구현하게 되어있다.
이는 SOLID원칙 중 O에 해당하는 것으로
“클래스는 확장에 열려있어야 하며 변경에 닫혀 있어야 한다.”
즉, 요구사항이 변경,추가 되더라도 기존 구성요소는 수정이 일어나지 않고 확장해서 재사용하는 것과 같다.
regist(); 입장에서는 요구사항이 추가되더라도 인터페이스를 이용하여 기존 요소에 if-else를 추가해 소스를 수정하지 않고,
인터페이스내에 새로운 방법을 추가하여 확장해서 재사용하는 것이다.
SOLID의 자세한 설명은 1장. 깨끗한 코드에(클릭하여 이동) 잘 나와있다.
단 추상화는, 처음부터 시도하는것보다는 개발을 하다가 공통적인 부분이나 확장할때 하면 된다.
처음부터 추상화를 하게되면 구조가 복잡해진다는 느낌을 받을 수 있고, 분석의 시간도 높아진다.
구현을 숨기다보니 가독성이 힘들어 지기도 하기 때문이다.
캡슐화와 추상화는 변화에 유연하지만 둘은 약간의 차이가 존재한다.
캡슐화 : 나의 구현이 바뀌어도 가져다 쓰는 애들은 변경이 되지 않는다.
추상화 : 내가 사용하는 애의 구현이 바뀌더라도 변경하지 않아도 된다.
'IT서적 & 세미나 > 사내 세미나' 카테고리의 다른 글
6주차 - CQRS (0) | 2022.03.03 |
---|---|
5주차 - 영역과 로직 (0) | 2022.03.03 |
4주차 - 아키텍처란? (DIP) (0) | 2022.03.03 |
2주차 - 캡슐화란? 자바에서 캡슐화 하는 이유. (0) | 2021.12.11 |
1주차 - 프로그래밍의 기능과 역할 (0) | 2021.12.11 |