반응형

전체 글 68

[만들면서 배우는 클린 아키텍처] 8장, 9장, 10장 정리

8장 경계 간 매핑하기각 계층의 모델을 매핑하는 것에 대한 논쟁매핑에 찬성하는 개발자 : 두 계층 간에 매핑을 하지 않으면 양 계층에서 같은 모델을 사용해야 하는데 이렇게 하면 두 계층이 강하게 결합된다.매핑에 반대하는 개발자 : 두 계층 간에 매핑을 하게 되면 보일러플레이트 코드를 너무 많이 만들게 되어서 많은 유스케이스들이 오직 CRUD만 수행하고 계층에 걸쳐 같은 모델을 사용하기 때문에 계층 사이의 매핑은 과하다.'매핑하지 않기' 전략웹 계층에서 웹 컨트롤러가 SendMoneyUseCase 인터페이스를 호출해 유스케이스를 실행한다. 이 인터페이스는 Account 객체를 인자로 가진다. 웹 계층과 애플리케이션 계층 모두 Account 클래스에 접근한다 (두 계층이 같은 모델을 사용)반대쪽의 영속성 계..

etc 2024.09.14

[만들면서 배우는 클린 아키텍처] 7장 정리

7장 아키텍처 요소 테스트하기 (육각형 아키텍처에서의 테스트 전략)테스트 피라미드테스트 피라미드에 따르면 비용이 많이 드는 테스트는 지양하고 비용이 적게 드는 테스트를 많이 만들어야 한다. 테스트의 기본 전제는 만드는 비용이 적고, 유지보수가 쉽고, 빨리 실행되고, 안정적인 작은 크기의 테스트들에 대해 높은 커버리지를 유지해야 한다.단위 테스트는 피라미드의 토대에 해당하며 일반적으로 하나의 클래스를 인스턴스화하고 해당 클래스의 인터페이스를 통해 기능들을 테스트한다. 만약 테스트 중인 클래스가 다른 클래스에 의존한다면 의존되는 클래스들은 인스턴스화하지 않고 테스트하는 동안 필요한 작업들을 흉내 내는 mock 으로 대체한다.통합 테스트는 연결된 여러 유닛을 인스턴스화하고 시작점이 되는 클래스의 인터페이스로 ..

etc 2024.09.14

[만들면서 배우는 클린 아키텍처] 5장, 6장 정리

5장 웹 어댑터 구현하기의존성 역전웹 어댑터는 '주도하는' 혹은 인커밍 어댑터다. 그림을 살펴보면 의존성 역전 원칙이 적용된 것을 발견할 수 있다.어댑터와 유스케이스 사이에 또 다른 간접 계층을 넣어야 하는 이유는 애플리케이션 코어가 외부 세계와 통신할 수 있는 곳에 대한 명세가 포트이기 때문이다. 위 사진에서는 어댑터가 엄밀히 말하면 아웃고잉 포트의 역할까지 같이 수행한다.5장에서는 웹 어댑터가 일반적인 인커밍 어댑터 역할만 한다고 가정한다.웹 어댑터의 책임웹 어댑터의 일반적인 역할은 다음과 같다HTTP 요청을 자바 객체로 매핑권한 검사입력 유효성 검증입력을 유스케이스의 입력 모델로 매핑유스케이스 호출유스케이스의 출력을 HTTP로 매핑HTTP 응답 반환웹 어댑터는 URL, HTTP 메서드, 컨텐츠 타입..

etc 2024.09.14

[만들면서 배우는 클린 아키텍처] 1장, 2장, 3장, 4장 정리

1장 계층형 아키텍처의 문제는 무엇일까?계층형 아키텍처는 크게 3가지 레이어로 나뉜다. 웹, 도메인, 영속성 레이어다. 계층을 잘 이해하고 구성한다면 웹 계층이나 영속성 계층에 독립적으로 도메인 로직을 작성할 수도있고, 도메인 로직에 영향을 주지 않고 웹 계층과 영속성 계층에 사용된 기술을 변경할 수 있다. 그리고 기존 기능에 영향을 주지 않고 새로운 기능을 추가할 수도 있다.잘 만들어진 계층형 아키텍처는 선택의 폭을 넓히고, 변화하는 요구사항과 외부 요인에 빠르게 적응할 수 있게 해준다. 그렇다면 계층형 아키텍처의 문제점은 무엇일까계층형 아키텍처는 코드에 나쁜 습관들이 스며들기 쉽게 만들고 시간이 지날수록 소프트웨어를 점점 더 변경하기 어렵게 만드는 많은 허점들이 있다.계층형 아키텍처는 데이터베이스 주..

etc 2024.09.14

[Thread] Spinlcok

spinlockCAS는 단순한 연산 뿐만 아니라, synchronized, Lock(ReentrantLock) 없이 락을 구현하는데 사용할 수도 있다.스레드를 대기없이 lock을 구현하는 방법인데, 이를 spinlock이라고 한다.public class SpinLockBad { private volatile boolean lock = false; public void lock() { log("락 획득 시도"); while (true) { if (!lock) { // 락 사용 여부 확인 sleep(100); // 문제 상황 확인, 스레드 대기 lock = true; // 어떤 스레드가 락을 획득한 ..

Java 2024.09.08

[Thread] Lock, ReetrantLock

ReetrantLock자바 1.0부터 지원하기 시작한 synchronized와 BLOCKED 상태를 통한 임계 영역 관리의 한계를 극복하기 위해 자바 1.5부터 Lock 인터페이스, ReentrantLock 구현체를 제공한다. package java.util.concurrent.locks;import java.util.concurrent.TimeUnit;public interface Lock { void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock(long time, TimeUnit unit) throws InterruptedException; vo..

Java 2024.09.07

[Thread] LockSupport

Lock supportLock support는 synchronized의 단점을 보완하기 위해 Java1.5부터 추가된 라이브러리 패키지다. synchronized의 단점은무한대기특정 시간까지만 대기하는 타임아웃X중간에 인터럽트X공정성락이 돌아왔을 때 BLOCKED 상태의 여러 스레드 중에 어떤 스레드가 락을 획득할 지 알 수 없어서 특정 스레드는 오랜기간 동안 락을 획득하지 못할 수 있다.Lock Support의 기능LockSupport는 스레드를 WAITING 상태로 변경한다. WAITING 상태는 누군가가 다시 상태를 변경하지 않으면 계속 대기상태고 CPU 실행 스케줄링에 들어가지 않는다.park() : 스레드를 WAITING 상태로 변경한다.스레드를 대기 상태로 둔다. parkNanos(nanos..

Java 2024.09.06

[Thread] CAS 연산

CAS 연산lock 기반 방식(synchronized)의 문제점은 데이터를 보호하기 위해 락을 사용하게 된다. 락은 특정 자원을 보호하기 위해 스레드가 해당 자원에 대한 접근하는 것을 제한한다. 락이 걸려 있는 동안 다른 스레드들은 해당 자원에 접근할 수 없고, 락이 해제될 때까지 대기해야 한다. 그리고 락을 획득하고 반납하는 과정에서도 시간이 소요된다. 락이 있는지 확인한다.락을 획득하고 임계 영역에 들어간다.작업을 수행한다.락을 반납한다. 1억번의 연산을 수행한다면 4가지 과정을 반복하게 된다. 이러한 문제를 해결하기 위해 락을 걸지 않고 원자적인 연산을 수행할 수 있는 방법이 CAS(Compare-And-Swap, Compare-And-Set) 연산이라 하고, 락을 사용하지 않기 때문에 lock..

Java 2024.09.03

[Thread] Atomic, volatile, synchronized 성능 비교

원자적 연산원자적 연산은 중단되지 않고, 다른 연산과 간섭 없이 완전히 실행되거나 전혀 실행되지 않는 성질을 가지고 있다. 멀티 스레드 상황에서 다른 스레드의 간섭 없이 안전하게 처리되는 연산이라는 뜻이다. volatile int i = 0;// 원자적 연산 -> 여러 스레드가 접근해도 i에 값만 할당하니까 문제 없다.i = 1;// 원자적 연산이 아니다 -> 여러 스레드가 동시에 접근하면 문제가 생길 수 있다.i = i + 1; Java에서 제공하는 Atomic 객체 성능 비교BasicInteger -> 아무 키워드, 아무것도 사용하지 않고 int값을 증가 시킨다.VolatileInteger -> 메모리 가시성을 비교 하기 위해 int 변수에 Volatile 키워드만 추가하고 int 값을 증가시킨다...

Java 2024.09.03

[Thread] synchronized

synchronized멀티스레드를 사용할 때 가장 주의해야 할 점은, 같은 리소스에 여러 스레드가 동시에 접근할 때 발생하는 동시성 문제다. 여러 스레드가 접근하는 자원을 공유 자원이라 하고, 멀티스레드를 사용할 때는 이런 공유 자원에 대한 접근을 적절하게 동기화(synchronized)해서 동시성 문제가 발생하지 않게 방지 해야 한다.public class BankAccountV1 implements BankAccount { private int balance; public BankAccountV1(int initialBalance) { this.balance = initialBalance; } @Override public boolean withdraw(int ..

Java 2024.09.02
반응형