본문 바로가기
반응형

혼자 공부하는 것들145

템플릿 메서드 패턴 GOF 디자인 패턴에서는 템플릿 메서드 패턴을 다음과 같이 정의했습니다. "작업에서 알고리즘의 골격을 정의하고 일부 단계를 하위 클래스로 연기합니다. 템플릿 메서드를 사용하면 하위 클래스가 알고리즘의 구조를 변경하지 않고도 알고리즘의 특정 단계를 재정의할 수 있습니다." [GOF] 부모 클래스에 템플릿을 정의하고, 일부 변경되는 로직은 자식 클래스에 정의하는 것입니다. 이렇게 하면 자식 클래스가 알고리즘의 전체 구조를 변경하지 않고, 특정 부분만 재정의할 수 있습니다. 결국 상속과 오버라이딩을 통한 다형성으로 문제를 해결하는 것입니다. 하지만 템플릿 메서드 패턴은 상속을 사용합니다. 따라서 상속에서 오는 단점들을 그대로 안고 갑니다. 특히 자식 클래스가 부모 클래스와 컴파일 시점에 강하게 결합되는 문제가.. 2022. 4. 25.
Spring에서 동시성 문제를 해결해보자! [+ThreadLocal] 예를 들어 보드게임 중 할리갈리라는 게임이 있죠. 어떤 과일이든 합이 5개가 된다면 빠르게 종(인스턴스)을 치고(스레드) 해당 카드를 가져가는 게임입니다. 이 상황과 비슷하다고 느껴지지 않나요? 동시에 하나의 종을 여러 플레이어가 접근하는 게임입니다. 간단하게 이야기해보자면, 여러 스레드가 동시에 같은 인스턴스의 필드의 값을 변경하면서 발생하는 문제를 동시성 문제라고 합니다. 이러한 동시성 문제는 지역 변수에서 발생하지는 않습니다. 자바에서 지역변수는 스레드마다 각각 다른 메모리 영역을 할당하기 때문입니다. 또한, 값을 읽기만 했을 경우 동시성 문제가 발생하지는 않습니다. 다른 곳에서 값을 변경할 때 문제가 생깁니다. 이런 동시성 문제는 여러 쓰레드가 같은 인스턴스의 필드에 접근해야 하기 때문에 트래픽이.. 2022. 4. 19.
메서드 시그니처를 신중히 설계하자! 메서드를 생성할 때 쓰기 쉬우며, 오류 가능성이 적은 API를 만드는 방법을 배워보겠습니다. ⚠️ 메서드 이름을 신중히 짓자 이해할 수 있고, 같은 패키지에 속한 다른 이름들과 일관되게 짓는 게 최우선 목표입니다. 긴 이름을 피하는 게 좋습니다. 애매하면 자바 라이브러리의 API 가이드를 참고하면 좋을 것 같습니다. ⚠️ 편의 메서드를 너무 많이 만들지 말자. 모든 메서드는 각각 자신의 소임을 다해야합니다. 메서드가 너무 많은 클래스는 학습, 사용, 문서화, 유지보수, 테스트하기가 정말 어렵습니다. 인터페이스도 마찬가지입니다. 아주 자주 쓰일 경우에만 별도의 약칭 메서드를 두는 방법도 있습니다. 확신이 서지 않으면 만들지않는 게좋습니다. ⚠️ 매개변수 목록은 짧게 유지! 매개변수는 4개 이하가 가장 이상.. 2022. 4. 9.
[index] B+-Tree, Hash Table 이번에는 인덱스에 관련돼서 정리해보려고 합니다. 간단하게 설명하자면 단어를 찾아보기 위해 백과사전을 보고 있다고 생각해봅니다. 이때 특정 단어를 검색해보기 위해 책장을 무수히 넘겨봅니다. 한 번은 이렇게 찾는다 쳐도 수 백번, 수 천 번 그런다면 정말 비효율적이겠죠? 이럴 때 필요한 게 목차입니다. 특정 단어의 위치를 목차에서 보고 위치를 유추할 수 있습니다. 이 역할을 하는 게 바로 인덱스입니다. 데이터베이스에서 인덱스란? 테이블에 대한 동작(검색)의 속도를 높여주는 자료 구조를 뜻합니다. 인덱스는 테이블 내의 1개의 컬럼, 혹은 여러 개의 컬럼을 이용하여 생성될 수 있습니다. 고속의 검색 동작뿐만 아니라 레코드 접근과 관련 효율적인 순서 매김 동작에 대한 기초를 제공합니다. 인덱스를 저장하는 데 필요.. 2022. 3. 19.
가변인수는 신중하게! 이펙티브 자바에서 읽었던 가변 인수에 대한 것을 정리해보았습니다. 가변 인수(varargs) 메서드는 명시한 타입의 인수를 0개 이상 받을수있습니다. 가변 인수 메서드를 호출하면, 가장 먼저 인수의 개수와 길이가 같은 열을 만들고 인수들은 이 배열에 저장하여 가변 인수 메서드에 건네줍니다. 인수가 1개 이상이어야 할 때도 있습니다. 예를 들어 최솟값을 찾는 메서드인데 인수를 0개만 받을 수도 있도록 설계하는 것은 좋지 않습니다. static int min(int... args){ if(args.length ==0){ throw new IllegalStateException("인수가 1개 이상 필요합니다"); } int min = args[0]; for(int i=0;i 2022. 3. 16.
[디자인패턴] Domain Model Pattern vs Transaction Script Pattern Domain Model Pattern [도메인 모델 패턴]이란? 대부분의 비즈니스 로직이 엔티티 안에 구성되어있습니다. 서비스 계층은 엔티티에 필요한 역할을 위임하는 역할을 합니다. 엔티티 안에 비즈니스 로직을 가지고 객체지향을 활용하는 기법입니다. (DDD를 접목시킬 경우 이 방법을 사용합니다.) Transaction Script Pattern [트랜잭션 스크립트 패턴]이란? 엔티티에 비지니스로직이 거의 없고, 서비스 계층에서 비즈니스 로직을 처리하는 방법을 가리킵니다. 엔티티는 단순하게 데이터를 전달하는 역할이 되면서 서비스 로직이 커지게 됩니다. 간단하게 주문 엔티티가 있다고 가정해봅니다. 도메인 모델 패턴으로 구현하면 @Entity @Table(name = "orders") @Getter @Set.. 2022. 3. 13.
익명 클래스하고 람다식은 어떤 상황일 때 사용해야할까? 이펙티브 자바라는 책을 읽던 중 람다 함수에 대해 궁금하여 정리해보았습니다. 간단하게 문자열을 길이 순으로 정렬하는데, 정렬을 위한 비교 함수로 익명 클래스로 사용한 방법을 확인해봅시다. Collections.sort(words, new Comparator(){ public int compare(String s1, String s2){ return Integer.compare(s1.length(), s2.length()); } }); 전략 패턴처럼 함수 객체를 사용하는 과거 객체지향 디자인 패턴에는 익명 클래스면 충분했습니다. https://ko.wikipedia.org/wiki/%EC%A0%84%EB%9E%B5_%ED%8C%A8%ED%84%B4 전략 패턴 - 위키백과, 우리 모두의 백과사전 전략 패턴(.. 2022. 3. 10.
[JPA] 엔티티 설계할 때 이 점을 주의하자! JPA를 공부하던 중 엔티티를 설계할 때 주의해야 할 점을 정리해보려고 합니다. 엔티티 설계시 가급적이면 Setter를 사용하지 말자! Setter가 모두 열려있으면, 변경점을 찾기 어렵고, 열어놓고 누군가 사용한다면 그 해당 로직을 쭉 읊으면서 변경점을 찾아야 한다는 번거로움이 있습니다. 또한, 리팩터링 하기가 다소 어렵습니다. 모든 연관관계는 지연 로딩으로 설정하자!(제일 중요!) 연관관계는 즉시 로딩과 지연 로딩이 있습니다. 즉시 로딩은 연관된 테이블을 로딩하는 시점에 모두 로딩해주는 방식입니다. 이 방식은 비추! 사용하면 안됩니다. 즉시로딩( EAGER )은 예측이 어렵고, 어떤 SQL이 실행될지 추적하기 어렵습니다. 특히 JPQL을 실행할 때 N+1 문제가 자주 발생합니다. 실무에서 모든 연관관.. 2022. 3. 5.
Spring Boot에서 타임리프 이미지 동적 리소스 사용하기 스프링 부트에서 타임리프를 사용하던 중 이미지를 업로드 후 파일이 즉시 반영이 안 되는 이슈가 있었습니다. 스프링에서 static 폴더는 정적 리소스 폴더인데 여기 안에서 사용자가 이미지를 업로드하고, 삭제, 이용하게 설계해서 이슈가 발생했습니다. 대부분 AWS S3나 외부 디렉터리를 사용하여 컨트롤러 라우터에서 이미지 path를 받고, 외부 디렉터리에서 파일을 가져와 이미지를 뿌려주는 방식입니다. 여기서 중요한 점은 파일이 업로드한다고 해서 바로 웹 리소스로 쓸 수 없습니다. 컨트롤러에 한 번 요청해서 내려줘야 합니다. /resources/user 유저가 파일을 업로드하면 위와 같은 위치에 파일을 저장하게 됩니다. 여기서 웹 리소스로 한 번 더 매핑해서 내려주는 작업을 해주어야 합니다. package .. 2022. 2. 23.
반응형