라이브러리 vs 프레임워크
- 라이브러리 -> 공통으로 사용될 수 있는 특정한 기능들을 모듈화한 것
- '나'가 가위질을 하는 것
- 규약이 적다
- axios
- 프레임워크 -> 공통으로 사용될 수 있는 특정한 기능들을 모듈화한 것
- '비행기'에 타는 것
- 규악이 많다
- 다른 라이브러리 or 프레임워크에 옮기기 힘들다 (= 이식성 낮음)
- Vue.js
디자인 패턴
- 프로그램 설계시 -> 발생했던 문제들을 해결하도록 '규약'을 만들어 놓은 것
- 무엇으로? -> 객체 간 상호 관계를 통해서
싱글톤 패턴
- 하나의 클래스 기반 -> 단 하나의 인스턴스를 여러개 생산
- 데이터 베이스에 많이 사용 -> 인스턴스 생성 비용 절감
-
예시
- mongoose 싱글톤 패턴 -> node.js에서 MongoDB 데이터베이스에 연결할 떄
- MySQL 싱글톤 패턴 -> node.js에서 MySQL 데이터베이스에 연결할 때
-
장점
- 하나의 인스턴스를 기반 -> 인스턴스를 여러 모듈들이 '공유' -> 인스턴스 생산 비용 감소 -> 인스턴스 생성에 많은 비용 드는 I/O 바운드 작업에 사용
-
단점
- 의존성 높음 -> TDD(단위 테스트)할때 걸림돌, 독립적인 테스트를 해야하는데 하지 못해서, 어떤 순서로든 가능해야 함(A -> B, B -> A)
싱글톤 패턴 구현 방식
- basic
- 단순한 메소드 호출 방식 -> 싱글톤패턴 여부 확인 -> 없으면 새로 생성
- 단점
- 원자성 결여 -> 멀티스레드 환경에서는 인스턴스 2개 생성 가능
- 한쪽의 thread가 sleep하면 다른 thread가 실행의 가능성
- 단점 해결 방법 -> sychronized
- synchronized
- 인스턴스를 반환 전까지 'synchronized'로 lock 해버리는 것 -> 최초 thread가 끝날 때까지 다른 thread가 접근 X
- 단점
- 단점 해결 방법 -> static member, static block
- static member, static block
- 클래스 로딩할떄 미리 인스턴스를 생성하는 방법 -> 정적 영역에 생성
- 단점
- 자원낭비 -> 인스턴스 생성이 필요없을 때도 그냥 생성
public class Singleton {
private final static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
reuturn instance;
}
}
public class Singleton {
private static Singleton instance = null;
static {
instance = new Singleton();
}
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
- LazyHolder
- singleInstanceHolder란 내부클래스 하나 더 생성 -> Singleton 클래스의 Instance() 가 호출될 때 내부 클래스가 로딩되어 인스턴스 생성
- 즉, 필요할 때만 정적 멤버로 할당
class Singleton {
private static class singleInstanceHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() }
return singleInstanceHolder.INSTACE
}
}
-
DCL
- 이중 확인 잠금(Duble Checked Locking)
- volatile -> instance 변수 앞에 사용
- Java는 thread 가 열리면 각각의 CPU cache 메모리에서 가져옴
- volatile 사용 -> CPU cache 메모리 X / Main 메모리 ㅇ(공유)
-
ENUM
- enum의 instance는 기본적으로 thread safe한 점이 보장
- 현존 최고의 방법쓰
public enum Singleton {
INSTANCE;
public void hypeBoy() {
}
}