2022-06-27-TIL
Today I Learned
Java Generics and Wildcard
제네릭 와일드카드에서 가장 헷갈리는 것은 ? extends T와 ? super T 중 무엇을 쓸지다. Java 튜토리얼의 와일드카드 사용 지침은 변수를 “in”과 “out”으로 나눠 생각하라고 한다.
- “in” 변수는 코드에 데이터를 제공한다.
copy(src, dest)에서src가 여기에 해당하고, 상한 와일드카드(? extends T)로 선언한다. - “out” 변수는 다른 곳에서 쓸 데이터를 담는다.
copy(src, dest)에서dest가 여기에 해당하고, 하한 와일드카드(? super T)로 선언한다. - “in” 변수를
Object의 메서드만으로 다룰 수 있다면 비한정 와일드카드(?)를 쓴다.
1
2
3
4
5
static <T> void copy(List<? extends T> src, List<? super T> dest) {
for (T item : src) { // src에서 꺼내기만 한다
dest.add(item); // dest에는 넣기만 한다
}
}
List<? extends Number>에서는 원소를 Number로 꺼낼 수 있지만, 실제 타입이 List<Integer>인지 List<Double>인지 모르므로 null 외에는 넣을 수 없다. 반대로 List<? super Integer>에는 Integer를 넣을 수 있지만, 꺼낸 값은 Object로만 받을 수 있다. 꺼내는 쪽은 extends, 넣는 쪽은 super라고 기억하면 된다.
- https://thecodinglog.github.io/java/2020/12/15/java-generic-wildcard.html
Ston Edge CDN
STON은 엣지 서버 소프트웨어다. STON Edge Server 문서는 엣지를 서비스의 가장 바깥, 고객이 속도와 가용성을 직접 체험하는 계층으로 설명한다.
엣지 서버는 요청에 따라 동작하는 캐시 방식이다.
- 첫 번째 요청을 받으면 원본 계층에서 콘텐츠를 가져와 고객에게 보내고, 자기 자신에게도 저장한다.
- 두 번째 요청부터는 저장한 콘텐츠를 바로 보낸다.
- 저장된 콘텐츠는 미리 설정한 TTL(Time-To-Live) 동안 유효하다.
이미지, 동영상, 정적 파일처럼 여러 사용자가 같은 콘텐츠를 요청하는 경우, 엣지가 대부분의 요청을 처리하면 원본 애플리케이션 서버와 스토리지를 덜 늘려도 된다. 반대로 콘텐츠가 바뀌었는데 TTL이 남아 있으면 이전 콘텐츠가 나가므로, 갱신이 잦은 콘텐츠는 TTL을 짧게 하거나 캐시를 비우는(purge) 절차를 함께 설계해야 한다.
- https://ston.readthedocs.io/ko/latest/admin/intro.html#edge
Jedis Pool
Jedis는 Java용 Redis 클라이언트다. Redis에 명령을 보낼 때마다 연결을 새로 열고 닫으면 비용이 크기 때문에 커넥션 풀을 쓴다. Redis의 Jedis 운영 가이드도 연결을 반복해서 열고 닫는 것은 성능 오버헤드가 있으니 커넥션 풀을 쓰라고 권한다.
Jedis 4.2.0 README의 기본 사용법은 JedisPool에서 연결을 빌리고, try-with-resources로 반드시 돌려주는 것이다.
1
2
3
4
JedisPool pool = new JedisPool("localhost", 6379);
try (Jedis jedis = pool.getResource()) {
jedis.set("key", "value");
}
close()를 호출해야 연결이 풀로 돌아간다. 이를 빠뜨리면 빌린 연결이 반환되지 않고 쌓여, 풀의 최대 개수(maxTotal)에 도달한 뒤에는 다른 요청이 연결을 얻지 못한다. README는 매번 try 블록을 쓰는 것이 번거로우면 풀 관리를 내부에서 해 주는 JedisPooled를 쓰라고 안내한다. 풀 크기는 ConnectionPoolConfig의 setMaxTotal, setMaxIdle 등으로 정한다.
- https://theserverside.tistory.com/302
- https://blog.leocat.kr/notes/2016/08/20/redis-max-connection-problem
Git 브랜치 간 변경사항 선택적으로 합치기
다른 브랜치의 변경을 통째로 merge하지 않고 일부만 가져오는 방법은 단위에 따라 다르다.
- 커밋 단위:
git cherry-pick은 지정한 기존 커밋들이 만든 변경을 현재 브랜치에 다시 적용한다. - 파일 단위:
git checkout <tree-ish> -- <pathspec>은 다른 브랜치의 특정 파일 내용을 현재 작업 트리로 가져온다. - 변경 조각(hunk) 단위:
git checkout -p <tree-ish> -- <pathspec>은 diff를 대화형으로 보여 주고, 가져올 조각을 하나씩 고르게 한다.
1
2
3
git cherry-pick a1b2c3d
git checkout feature/login -- src/main/java/LoginService.java
git checkout -p feature/login -- src/main/java/LoginService.java
cherry-pick은 같은 변경이 다른 커밋 해시로 한 번 더 생기므로, 나중에 원래 브랜치를 merge할 때 충돌이 나거나 이력이 헷갈릴 수 있다. 일시적인 핫픽스 반영처럼 이유가 분명할 때 쓴다.
- https://mylko72.gitbooks.io/git/content/branch/merge.html
- https://cselabnotes.com/kr/2021/03/31/56/
Blackship Study
Transaction Script
마틴 파울러의 Transaction Script는 비즈니스 로직을 프로시저 단위로 조직하는 패턴이다. 대부분의 업무 애플리케이션은 일련의 트랜잭션으로 볼 수 있고, Transaction Script는 각 트랜잭션의 로직을 하나의 프로시저에 담아 DB를 직접(또는 얇은 래퍼를 거쳐) 호출한다.
Spring 프로젝트에서 서비스 메서드 하나가 조회, 검증, 계산, 저장을 모두 순서대로 하고 엔티티는 getter, setter만 가진 구조가 전형적인 예다. 로직이 단순할 때는 이해하기 쉽고 빠르게 만들 수 있다. 하지만 규칙이 늘어나면 비슷한 검증과 계산이 여러 서비스 메서드에 중복된다.
대비되는 패턴이 Domain Model이다. 행위와 데이터를 함께 가진 객체들의 그물로 도메인을 표현하고, 규칙을 해당 데이터를 가진 객체 안에 둔다. 복잡한 비즈니스 로직을 다루기 위한 패턴이지만, 그만큼 설계 비용이 든다.
- https://velog.io/@hoyun7443/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%8C%A8%ED%84%B4-vs-%EB%8F%84%EB%A9%94%EC%9D%B8-%EB%AA%A8%EB%8D%B8-%ED%8C%A8%ED%84%B4
CRC Card
CRC 카드는 Kent Beck과 Ward Cunningham이 OOPSLA’89에서 발표한 A Laboratory For Teaching Object-Oriented Thinking에서 소개한 기법이다. CRC는 Class, Responsibility, Collaboration의 약자로, 객체를 클래스 이름, 책임, 협력자로 기술한다. 논문에서는 객체 하나를 4x6인치 인덱스 카드 한 장에 적는다.
1
2
3
4
5
6
7
+---------------------------+------------------+
| Order | |
+---------------------------+------------------+
| 책임 | 협력자 |
| - 주문 금액을 계산한다 | OrderLine |
| - 주문을 취소한다 | Payment |
+---------------------------+------------------+
논문은 이 카드를 실행 시나리오와 함께 쓴다. 시나리오를 따라가며 “이 요청은 누가 처리하지?”를 묻고, 카드를 직접 집어 들거나 옮기면서 책임을 나눈다. 저자들은 이렇게 카드를 물리적으로 다루는 것이 객체를 이해하는 데 생각보다 큰 도움이 됐다고 적었다. 데이터가 아니라 책임과 협력에서 출발해 객체를 나누는 연습이라는 점에서, 앞의 Domain Model과 같은 방향이다.
- https://ko.wikipedia.org/wiki/CRC_%EC%B9%B4%EB%93%9C
댓글
아직 댓글이 없습니다