분류 전체보기
TestContainers가 Docker 감지 못 하는 문제 (Mac)
발생 TestContainers를 활용해서 통합 테스트를 작성하고 실행하는데 오류가 발생했습니다. 분명히 도커는 백그라운드에 실행 중인데 말이죠... 에러 Could not find a valid Docker environment. Please see logs and check configuration 해결 https://www.testcontainers.org/supported_docker_environment/ 테스트 컨테이너 홈페이지에서 도커 환경과 관련한 내용을 읽어보다가 답을 찾았습니다. Mac OS의 경우에 위처럼 도커를 찾지 못할 경우 아래의 명령어를 터미널에 입력하면 될 겁니다. sudo ln -s $HOME/.docker/run/docker.sock /var/run/docker.sock
[Docker] IntelliJ에서 MySQL Connection 실패
도커를 실행하고도 IntelliJ에서 기존에 사용하던 MySQL DB를 찾지 못하는 오류가 있었습니다. docker ps로 확인해봤더니 없어졌네요...? 도커에 설치된 이미지를 확인해봤더니 기존에 설치했던 게 잘 있었네요! 그래서 docker ps -a로 옵션을 주어 Exited 된 것을 확인했습니다. (따로 설정한 적도 없는데요...ㅠㅠ) docker restart 로 해당 이미지를 다시 재실행시켜주었더니 정상적으로 Connection이 됩니다. 도커를 잘 모르는 것이 여실히 느껴졌던 경험입니다. 차근차근 공부해야겠네요. 다른 분들은 저 같은 실수하지 마세요 ㅠㅠ
[Design Pattern] 템플릿 메서드 패턴 (Template Method)
Template Method 템플릿 메소드는 부모 클래스에서 알고리즘 뼈대를 정의하고, 자식 클래스에서 구조를 변경하지 않고 특정 단계를 재정의하는 행위 디자인 패턴입니다. 이미지에서 볼 수 있듯이 세 개의 DataMiner의 mine 메소드는 알고리즘 뼈대가 동일합니다. 그러나 각각 따로 구현하여 코드의 중복이 매우 많고 추가될 클래스에도 중복된 코드를 작성하게 되므로 유지보수성이 떨어집니다. DataMiner라는 인터페이스 또는 추상 클래스를 정의하고 mine 메소드 내부 로직에서 호출하는 메소드만 자식 클래스가 재정의하게 된다면 어떻게 될까요? 보이는 것과 같이 다형성도 살릴 뿐 아니라 유지보수가 매우 간단해집니다. 정형화된 패턴을 UML 클래스 다이어그램으로 표현하면 아래와 같습니다. 장점 알고리..
[Design Pattern] 추상 팩토리 패턴 (Abstract Factory)
Abstract Factory Pattern 추상 팩토리 패턴은 서로 관련 있는 객체들의 구상 클래스들을 일일이 지정하지 않고 인터페이스를 통해 일관성 있게 생성할 수 있는 생성 디자인 패턴입니다. 현실과 거리가 멀지만 한 가지 예시를 들어보겠습니다. 삼성과 애플의 노트북 생산 공장에서 각 사에서 자사 또는 LG의 디스플레이(Display)와 본체(Body)를 조립한다고 가정해보겠습니다. 팩토리 메서드 패턴만 적용한 상태에서 다음과 같은 다이어그램을 그릴 수 있습니다. 이 경우에는 LaptopFactory에서 클라이언트에서 전달받은 Samsung 또는 Apple 키워드를 DisplayFactory와 BodyFactory에 각 부품 생산을 위임하고 실제 DisplayFactory와 BodyFactory의..
[Design Pattern] 팩토리 메서드 패턴 (Factory Method)
Factory Method Pattern 부모 클래스에서 객체들을 생성할 수 있는 인터페이스만 제공하고 실제 생성될 객체들의 유형을 자식 클래스들이 결정할 수 있도록 하는 생성 디자인 패턴입니다. 즉, 클라이언트 코드가 구상체에 의존하지 않고 추상 메소드를 통해서 생성될 자식 클래스를 지정할 수 있습니다. 예시 구조는 다음과 같습니다. 장점 개방 폐쇄 원칙(OCP)를 준수합니다. 기존 클라이언트를 변경하거나 수정하지 않고 확장이 가능합니다. 단점 패턴을 구현하기 위해 많은 클래스를 만들어야 하므로 복잡해질 수 있습니다. 참조 refactoring.guru 위키백과
[Design Pattern] 어댑터 패턴 (Adapter)
Adapter Pattern 서로 다른 또는 호환되지 않는 인터페이스를 가진 객체들이 호환될 수 있도록 하는 구조적 디자인 패턴입니다. 어댑터라는 단어는 일상에서 많이 들어본 단어일 겁니다. 데스크톱과 모니터에 전원을 공급할 때 우리는 220V에서 해당 장치가 사용할 수 있는 다른 전압으로 바꿔주는 것처럼 어댑터 패턴에서의 어댑터란 클라이언트가 연결하고자 하는 서로 다른 스펙을 가진 대상과 연결될 수 있도록 해주는 변환기인 셈입니다. 장점 단일 책임 원칙(SRP)을 준수합니다. 프로그램의 기본 비즈니스 로직에서 인터페이스나 데이터 변환 코드를 분리할 수 있습니다. 개방 폐쇄 원칙(OCP)을 준수합니다. 클라이언트가 인터페이스를 통해 어댑터와 연결되는 경우 기존 클라이언트 코드를 수정/변형하지 않고 새롭게..
[Design Pattern] 데코레이터 패턴 (Decorator)
Decorator Pattern 기능을 확장할 때 기존 클래스를 서브 클래싱 하여 확장하는 경우 어떤 문제가 발생할까요? 앱 푸시 라이브러리를 개발한다고 생각해봅시다. 상위 클래스인 Notifier 클래스에는 여러 필드와 생성자가 있고, 이메일을 통해 알림을 전송하는 send 메소드가 있습니다. 사용자가 SMS, 카카오톡, 인스타그램, 슬랙 같은 채널을 통해서 알림을 받고 싶어 할 때 우리는 Notifier를 상속받는 SMS Notifier, Kakao Notifier 같은 하위 클래스로 확장할 수 있습니다. 그런데 만약 연결된 모든 채널로 부터 알림을 받거나 특정한 채널의 조합으로 알림을 받고 싶어 한다면요? 이런 방식으론 최악의 경우 모든 경우의 수에 맞춰 서브 클래싱 하게 될 수 있습니다. 여러 기..
[Design Pattern] 프록시 패턴 (Proxy)
Proxy Pattern 프록시는 다른 대상에 대해서 대체자 또는 Placeholder를 제공할 수 있는 구조적 디자인 패턴입니다. 프록시는 원래 개체에 대한 액세스를 제어하므로 요청이 원래 개체에 전달되기 전 또는 후에 작업을 수행할 수 있습니다. 즉, 프록시(Proxy) 뜻 그대로 대신하여 어떠한 역할을 수행한다는 것으로 이해하면 됩니다. 개체를 참조할 때 직접 참조하지 않고 대리자를 통해서 접근한다면 개체의 메모리에 직접 접근하지 않고 개체를 참조할 수 있을 뿐 아니라 필요한 시점까지 개체의 생성, 수정, 삭제를 미룰 수 있습니다. (완벽히 같지는 않지만 비슷한 예로 CDN을 떠올리면 좋을 것 같습니다!) 장점 OCP(개방/폐쇄 원칙)을 준수합니다. 서비스 또는 클라이언트를 변경하지 않고 새 프록시..
[Design Pattern] 싱글톤 패턴 (Singleton)
Singleton Pattern Singleton Pattern은 클래스의 인스턴스가 하나이면서 해당 인스턴스에 대해 전역적으로 접근할 수 있도록 하는 디자인 패턴입니다. 설정이나 관리를 위한 어떠한 역할을 수행하는 인스턴스가 단 하나만 존재해서 관리하도록 하는 등에 사용됩니다. 장점 클래스에 인스턴스가 하나만 있음을 확인, 보증할 수 있습니다. 다른 클래스의 인스턴스들이 싱글톤 인스턴스에 접근하기 쉽습니다. 메모리 영역에 할당되는 인스턴스가 하나이므로 *메모리를 낭비하지 않을 수 있습니다. 단점 싱글톤 인스턴스가 전역적인 접근을 처리하다 보면 다른 클래스 인스턴스와 결합도가 높아져 단일 책임 원칙을 위반할 수 있습니다. 멀티 쓰레드 환경에서 동기화 처리를 하지 않을 경우 다중 인스턴스가 생성되는 등의 ..
[Java] Functional Interface와 익명 클래스
자바에서는 default, static 메소드를 제외한 단 하나의 추상 메소드만 가진 인터페이스를 Functional Interface라고 합니다. interface 선언부 상단에 @FunctionalInterface라는 Annotation을 붙일 수 있습니다. (Java 8 이상) 또 Functional Interface에 있는 추상 메소드를 함수라고 부릅니다 ! Functional Interface @FunctionalInterface interface MyExample { void exam1(); default void exam2() {}// 상관 없습니다. static void exam3() {}// 상관 없습니다. } 익명 클래스 우리가 처음 인터페이스를 배울 때 문법으로는 인터페이스의 인스턴스..