일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- js fetch
- javascript api 호출
- gradle 모듈 프로젝트
- jpa 플러시
- jpa 플러쉬
- js await
- springboot 모듈
- springboot gradle 모듈 프로젝트
- javascript async
- javascript fetch
- 코틀린
- 코틀린 클래스
- Flutter
- JavaScript
- 스프링부트
- 코프링
- 준영속상태
- javascript async await
- JPA플러쉬
- spring 모듈 프로젝트
- JS
- JPA플러시
- js async await
- jpa 영속성
- spring gradle 모듈
- js api 호출
- ja async
- jpa준영속
- JPA
- JPA준영속 상태
- Today
- Total
매일 한줄 코딩
1주차 - 프로그래밍의 기능과 역할 본문
프로그래밍 종류
- OOP(Object-Oriented Programming) 객체지향 프로그래밍 (데이터 + 함수)
- FP(Functional Programming) 함수형 프로그래밍 (데이터와 함수를 분리)
- PP (Procedure Programming) 절차형 프로그래밍
기능(Function)이란?
기능은 입력(In) · 출력(Out) 으로 구성된다.
결국 A라는 기능은 입력과 출력으로 구성된다.
💡 ex) 로그인의 기능에서 사용자가 ID/PW를 입력하게되면, 결과로써 로그인을 시켜주거나, 혹은 로그인이 되지않거나의 출력으로 구성된다.
위의 예시의 IN, OUT은 명시적인 IO 이다.
대표적으로 스프링에서는 controller → service → dao → DB 이러한 절차로 기능이 실행될 것인데 이것은 의존의 형태를 띈다.
- 기능명세
- IN
- 명시적
- 암묵적
- OUT
- 명시적
- 암묵적
- IN
기능 명세는 위에 같은 형태를 띄게 되는데, 여기서 예로 명시적인 IN은 파라미터 혹은 Request가 될 것이다.
이때 IN,OUT 파라미터로 주지않는 모든것은 암묵적인 IO이다. 암묵적인 IO는 의존의 형태를 띄게된다.
암묵적인 IO는 의존이 될 가능성이 있다.
예시를 하나 들어보면..
💡 ex) IN: regist(...)란 함수, OUT: 결과 or 예외 일때, 기능: 회원가입시 이메일로 보내주세요.
위와같이 IN, OUT이 결정되었고, 기능은 회원가입시 이메일로 보내달라는 기능을 프로그래밍한다고 가정해보자.
여기서 회원가입시 확인해야할 유효성체크, 중복확인, 암호화, 가입처리, 이메일 전송의 기능까지 + 하였다.
....
....
// ex
public void regist(Request request) {
try {
// 유효성체크 - 아이디가 이메일 형식인지 체크한다.
if (request.getId().contains("@") == false) {
throw new BadRequestException();
}
// 유효성체크 - 비밀번호 유효성 체크
String regExp = "([0-9].*[!,@,#,^,&,*,(,)])|([!,@,#,^,&,*,(,)].*[0-9])";
Matcher matcher = Pattern.compile(regExp).matcher(request.getPassword());
if(matcher.find() == false) {
throw new BadRequestException();
}
...
// ID 중복 확인
boolean IsDuplicationId = dao.getDuplicationId(request.getId());
if( IsValidId == false) {
throw new DuplicationIdException();
}
...
// 암호화
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(msg.getBytes());
String encryptionPassword = bytesToHex(md.digest());
...
// DB에 저장.
Member member = new Member();
member.setId(request.getId());
member.setPassword(encryptionPassword);
...
dao.registMember(member);
...
// 이메일 전송
...
Authenticator auth = new SMTPAuthenticator("계정 아이디", "계정 비밀번호");
Session mailSession = Session.getDefaultInstance(props, auth);
MimeMessage mailMessage = mailImpl.createMimeMessage();
MimeMessageHelper message = new MimeMessageHelper(mailMessage, isAttach, "UTF-8");
message.setTo(request.getId());
message.setFrom("admin@abcdefg.co.kr");
message.setSubject("회원가입을 축하합니다.");
message.setText("축하한다.", true);
mailImpl.setJavaMailProperties(props);
mailImpl.setSession(mailSession);
mailImpl.send(mailMessage); //발송
...
} catch (Exception e) {
// 예외 처리...
}
}
위처럼 regist(..) 함수를 구현하게 된다면,
regist안에서 각종 세부기능들이 regis에 의존이 높아졌고, 하위기능들이 많아졌다.
기능 → 하위기능
기능아래의 하위기능들이 하나의 기능안에 너무 널브러져 있는 형태로 개발이 계속 진행된다고 가정한다면
추후에 regist(...)기능에 ID중복뿐만 아니라 이름, 전화번호도 같이 중복확인 해달라는 기능이 추가해달라고한다면 소스는 점점 늘어날 것이다.
그렇기 때문에 하위기능들은 각자의 책임과 역할을 각각 하나의 기능에 나열하지않고, OOP의 특성을 살려서 각각의 비지니스로직을 구현하고 호출하는 방식으로 변환하는게 좋을 것이다.
현재 위의 regist(...)함수는 마치 절차형 프로그래밍화 되어 보이기까지 한다.
때문에 저런 경우에서는
....
....
// ex
public void regist(Request request) {
try {
valid(request); // 유효성검사
duplicationId(request.getId()); // ID 중복확인
String encryptionPassword = encryption(request.getPassword()); // 암호화
...
dao.registMember(member); // DB저장
sendMail(member); // 메일전송
} catch (Exception e) {
// 예외 처리...
}
}
위 같이 각각 regist(...)함수의 구현부는 별도의 기능을 담당하는 함수를 따로 호출하도록 변경하였다.
그런데..? regist(...)는 결국 여러개의 기능들로 이루워져있는건 마찬가지이니 의존이나 하위기능들이 있는건 마찬가지가 아닌가? 라는 생각을 할 수 있다.
regist(...)는 하나의 IN과 하나의 OUT으로 구성된 것이고,
그안에 valid역시도 IN, OUT으로 구성되어있다.
나머지 함수들도 그렇게 구성되어 있는 형태인 것이 차이라고 볼 수 있다.
'IT서적 & 세미나 > 사내 세미나' 카테고리의 다른 글
6주차 - CQRS (0) | 2022.03.03 |
---|---|
5주차 - 영역과 로직 (0) | 2022.03.03 |
4주차 - 아키텍처란? (DIP) (0) | 2022.03.03 |
3주차 - 추상화란? 어떨때 추상화를 하면 좋을까? (0) | 2021.12.21 |
2주차 - 캡슐화란? 자바에서 캡슐화 하는 이유. (0) | 2021.12.11 |