본문 바로가기

세미나

KSUG 2019년 하반기 세미나 후기

1. 참가 신청 및 정보

이번 ksug 세미나는 장소가 협소한 관계로 선발 인원 수에 제한(90명)이 있었습니다. ksug 세미나 페이지 에서 티켓 구매를 누르면 네이버 예약으로 넘어가서 신청할 수 있었는데 1분만에 매진이 완료가 될 정도로 경쟁률이 높았습니다. 팁을 드리자면 저는 웹툰 보려고 네이버 페이 포인트를 충전해놨었는데 이번 티켓팅에 유용하게 썼습니다. (물론 내년에도 업체에서 네이버 예약을 쓴다면 유효한 팁이겠죠?)

2. 세미나 내용(키워드 위주 정리)

“코드를 테스트하는 다양한 방법” - 백기선 님


JUnit 5 달라진 점

@DisplayName() - 메소드의 이름을 설정할 수 있다.
assertAll()

assertThrow()
@ignore -> @Disabled
JUnit4에서 지원하지 않던 기능들이 추가됨

한 테스트 클래스에 정의된 메소드의 수만큼 테스트 클래스의 인스턴스를 새로 만든다. -> 메소드 간의 의존성을 겹치지 않게 하기위함

근데 @TestInstance(Lifiecycle_PER_CLASS) -> 로 설정하면 인스턴스 하나만 만들도록 설정 가능

@Runwith(SpringRunner.class) 생략 가능해짐

 

Mokito 
@RequiredArgsContructor
@ExtendWith(MokitoExtension.class)
@MockBean
위와 같이 쓰면 매번 생성안해도 됨
Stubbing - mock 객체가 어떻게 동작할지를 알려주는 것
when().theReturn() 
given, when, then -> given().willReturn()
verification 
verify() -> 순서대로 호출이 됐는지, 생성은 됐는지 확인
@TestContainer -> 테스트로 디비 연결을 할 수 있다. -> 도커로 디비를 띄워놓고 하던지, 따로 띄우던지 해야됨
spring.properties.active
watingForHostPost
@Tag -> 새로 추가됨 , 로컬, 개발 환경에서의 테스트 분리, 
카오스 몽키 신기하다. -> 일부러 발생 가능한 에러를 발생시키거나 지연시켜서 테스팅 해볼 수 있음

 

“null 서바이벌 가이드” - 박성철님
책임을 가지는 코드에 대한 이야기
null 과 null 안전성
10억달러짜리 실수 null - 토니 호어
null참조의 기원 : 레코드 핸들링의 널 참조
이진트리의 관계에서 더 이상 자식이 없는 상태? 를 null로 명명함 
사피엔스 라는 오류 점검 툴
모호한 null의 의미 (초기화되지않음, 의미없음)
null안전성 언어 지원 
null 병합 연산자
첫 인자가 null이면 nulll을 반환 아니면 인자를 반환
3항 연산자의 단축형 : a ? : b 는 a != null ? a : b 와 동일
앨비스 연산자
null 조건

첫 인자가 null이면 null을 반환 아니면 두번째 인자의 작업을 실행하는 이항 연산자
let zipcode - user? .address? .zicode;
type system 강화
null안전한 좋은 코딩 법
기본으로 null을 쓰지 말자 - 필요할 때만 Null을 쓰자?
null 문맥을 제한된 범위 안에 가두자
컴싸는 진보하지 않았다. software wig? 낮은 응집 높은 결합, < 늪은 응집 낮은 결합
작게 나눠라
똥을 작게 나눠? 
작게 나누되 냄새가 안나는 똥을 만들자(원래는 컴퓨터를 예시로 했다고 함) 
좋은 캡슐화란 ?
높은 응집성 : 한가지 책임만 같는다
모든 필드가 객체와 생명주기가 같아야한다
모든 메서드가 모든 필드를 대상으로 작업한다.
낮은 결합
디미터 법칙 , 묻지말고 시켜라 
인터페이스에 의존
디미터 법칙(Law of Demeter)
이런 형식을 갖추면 좋은 코드가 나올거야!
객체의 과도한 결합을 낮출 수 있는 형식적 규칙
오브젝트 p 184
도트 하나만 사용하라?
객체의 과도한 결합을 낮출 수 있는 ?
대표적 예시 : DDD 에그리것
API에 null을 최대한 쓰지 말아라
null로 지나치게 유연한 메서드를 만들지 말고 명시적인 메서드를 만들어라
null을 반환하지 말라
빈 컬렉션이나 nulll 객체를 활용하라
반환 값이 없을 수도 있음 명시적으로 optional 로 표현하라
오류 상황에서는 null을 반환하지말고 exception을 던져라
선택적 매개 변수는 null대신 정적 다형성를 사용해서 표현해라
null 객체를 활용하자 
null 객체(특수 사례 패턴)
인터페이스는 동일하지만 아무일도 하지 않는 일종의 더미 객체
이 객체와 협력하는 객체는 더미라는 사실을 몰라야함
리스코프 치환원칙 주의
타입안전하면서 의미를 표현할 수 있는 동일 타입의 특수 상황용 객체를 null 대신 반환
디미터 법칙과 묻지말고 시켜라를 잘 지켜야 유용 tell dont ask
null 객체를 사용할 상황
한 객체에 다른 객체가 
null을 명시적으로

null은 모든 참조타입의 상태
null은 참조값이 없음 나타내는 암시적 표현 방법
optional을 쓰라
optional은 상자, 갑이 입ㅆ을 수도 있고 없을 수도 있다는 것을 표현하는 컨테이너
값 기반 객체 -> 자바에서 만들고 있는? 자바 직렬화와 호환 문제로 당분간 직렬화 불가능 value based object
참조 타입으로 취급하지 말아라
직렬화를 못해 -> 우리가 쓰는 디티오의 멤버로 쓸 수 없어짐. -> 그래서 쓰면 안됨
그래서 일단 반환값으로만 쓰자고 하고 있는데 변할 수 있다?
불필요한 기본 타입용 옵셔널을 제공 중
optional - the mother of all bikesheds
절대로 optional 변수와 반환값에 nul을 사용하지 말라
isPresent() 쓰지 말라? 만들어놓고 잘못만들었다고 ㅋㅋ
계약에 의한 설계를 적용하자(Design by Contract)
api 규약을 소비자와 제공자 사이에 지켜야 할 엄격한 계약으로 여기는 설계 방법
내가 작성하고 있는 코드의 상태를 신경쓰지 않고 코딩할 수있게 만든
ocp 개방 페쇄 원칙 - 에펠(Eiffel)
형식적 규약 외에 사전 조건과 사후 조건과 유지 조건(불변식)을 포함
내 객체가 내가 설계한 대로 실행되고 있는걸 매번 확인하는? 체크하는? 그래서 예외를 날리는
그래서 안심하고 코딩을 할 수 있게 한다고?
자바의 계약에 의한 설계
자바용 DbC 전문 라이브러리는 거의 없음
자바 단정문(assertion)
assert 식1 ;
assert 식1 : 식2;
부울식인 식1의 거짓이면 AssertionError qkftod
식2는 Assetion
구조체에는 펑터(Functor)를 활용하자
자바는 절차지향 프로그래밍 기반의 객체지향 언어, 자바는 모든 타입이 객체지향이 아님
자바 클래스의 인스턴스가 모두 객체일 필요는 없다.
자바 클래스를 데이터 구조체로 적절히 사용가능(ex : dto)
구조체는 객체가 아니므로 디미터 법칙 적용 대상이 아님
optional  = 펑터(Functor)
객체의 기본값을 유용하게 만들자
객체를 생성했을 때 갖는 기본값이 쓰기에 문제 없어야 한다.
실행 전에 모든 필드가 초기화 되어야 한다.(지연 초기화 제외)
실행 시점에 Null인 필드는 초기화 되지 않았다는 의마가 아닌 값이 없다는 의미여야 한다.
객체 필드의 생명주기는 모두 객체의 생명주기와 같아얗한다.
null에 안전하다고 점검해주는 도구
null 안전성을 도와주는 자바 도구
정적 분석 도구 어노테이션 프로세싱
jsr 305
전문 정적 분석 도구
iDE 지원
어노테이션 프로세서(lombok, nullaway)
타입 시스템 확장
jsr 308
checkerFramework
jsr - 자바 표준 제안서 라는 것임
파인드 벅스 
인텔리제이 제공 어노테이션
JSR 305dml parametersAreNonullbydefault wldnjs
jsr 305를 참고한 독자 어노테이션

null은 왜 문제인가 - 모든 참조 타입에 지정 가능한 값(상태?), 언어가 지원할 문제
좋은 코드는 null에 안전하다.

 

“잘 키운 모노리스 하나 열 마이크로 서비스 안 부럽다” - 박용권님
마이크로 서비스에서 모노리틱으로 갈아탔다
이유 : 기술 부채 때문에? 일반적 상황과는 다른 이유네
너와 난, 우린 원래 하나였다.
하나의 디비를 여러 서비스가 보고 있다.
기능 수행에 코드가 분산되어 있으니, 순환 의존성을 띄게 된다. -> 비즈니스 요구사항을 수정하거나 기능을 확장할 때 걸림돌이 되기도 함.
배포의 문제도 여러개를 동시에 배포해야하는, 불합리한 일이 발생
커뮤니케이션의 문제
조직과 서비스 운영의 문제, 인원에 비해 많은 마이크로 서비스의 운영, 한 명이 여러개의 서비스를 만져야함.
결론 : 위와 같은 이유들로 인해 마이크로 서비스에서 모노리스로 갈아타기로 결정함!
모노리틱  vs 마이크로서비스
     둘을 대결구도로 놓는 경우가 많다.
     넷플릭스 와 아마존의 사례를 보여줌 -> 모든 서비스가 저렇지는 않지만 저런 구도로 많이 예시를 든다.
마이크로서비스가 주는 주요 혜택들
    조직 부합성
    조합성
    배포 용이성
    확장성
    회복성
    기술 이기종성
    대체 가능성
아키텍쳐 스타일을 바꾸면 문제가 해결되나? -> 큰 진흙 덩어리는 무엇을 하든 진흙이다.
응집과 결합을 다스리는게 먼저다.
응집도 : 응집이라는 것은 특정 행위를 변경하고자 할 때 한 곳에서만 변화가 일어나야하는 것, 하나의 기능을 고치기위해 여러군데에서 고치면 응집도가 낮다고 표현
결합도 : 서로 느슨하게 결합이 되어있다면, 하나의 변경이 또 다른 하나에 영향을 주지 않는다. 
모노리틱의 장점 
    빠른 구축
    하나의 레파지토리
    빠른 개발
모노리틱의 단점
    시스템이 커질 때의 문제
    새로운 사람의 학슴량 상승
마이크로서비스 : 서비스 단위로 독립 성장 가능, 기술의 다양성을 수용한다. 검색을 예로 특별한 검색을 위한 도구를 따로 만들 수 있다.
하지만 분산 시스템이 가지는 단점을 해결해야하고, 이런 것들이 동작하는 인프라의 구축을 해결해야함
이런 고민 끝에 잘 모듈화된 모노리틱으로 구축하기로 결정, 필요하다면 마이크로 서비스로 쉽게 확장이 되도록 만들기로
모듈형 모노리스 라는 발표를 보고 자신의 견해를 덧붙여서 구축 중
혼돈에서 질서로 가는 모듈화 -> 외부에 노출한 , 공개된 api 외에는 숨겨야한다. 충분히 느슨해야하고 독립적이어야 한다. 모듈이 공개한 인터페이스만 준수한다면 다른 모듈로 대체 가능해야한다.
관심사 분리로 변경에 유연한 아키텍처 -> 포텐 어뎁터 패턴
github.com/arawn
도메일 중심 모듈 구성으로 강한 응집도 얻어내기
의존성 관리로 모듈을 느슨하게 결합하기 
멀티프로젝트 구성과 의존관계 끊어놓기
모듈사이 경계를 넘어가지 못하게 격벽 쌓기
스프링 컨텍스트 계층 구조

 

3. 느낀 점

스프링, 자바 진영도 꾸준히 새로운 기술들을 영입하고있다는 것과 그것을 열정적으로 사용하는 사람들, 선구자들이 많다는 것을 느꼈습니다. 또 강연을 해주신 분들처럼 깊이 고민하면서 프로그램을 짜본 경험이 없었던 나로서는 신선한 충격과 좋은 자극을 느낄 수 있어 굉장히 유익한 시간이었습니다. 자신의 코드에 책임을 갖기 위해 목적성을 가진 공부를 해야한다는 말이 가장 기억에 남습니다. 레거시를 효율적으로 고치고, 더 나은 테스트 코드를 짜고, 자바 언어의 약점인 널 처리를 피하는 노력을 해야하는 이유에 대해 조금 더 이해할 수 있게 되어서 즐거웠습니다. 내년에는 더 나은 실력으로 참가할 수 있도록 많은 공부를 해야겠다는 다짐을 했습니다. ^^