5주차 정리
싱글턴 패턴
어떤 클래스의 객체 또는 인스턴스를 단 하나만 생성할 수 있다면, 해당 클래스는 싱글턴 클래스이며, 이 디자인 패턴을 싱글턴 패턴이라고 한다.
비즈니스 개념의 관점에서 클래스에 시스템에 한 번만 저장되어야 하는 데이터가 포함된 경우 해당 클래스는 싱글턴 클래스로 설계해야 한다.
싱글턴 패턴의 구현
싱글턴 패턴을 구현할 때 중점적인 4가지 조건
- 생성자는 new 예약어를 통한 인스턴스 생성을 피하기 위해 private 접근 권한을 가지고 있어야 한다.
- 객체가 생성될 때 스레드 안전성을 보장하는지 확인해야 한다.
- 지연 로딩을 지원하는지 여부를 확인해야 한다.
- getInstance() 함수의 성능이 충분해야 한다.
스레드 전용 싱글턴 패턴
스레드에서 유일한 것과 프로세스 내에서 유일한 것의 차이점
프로세스에서 유일하다 → 여러 프로세스 내에서 유일하다 X 하나의 프로세스 안에서 유일 O
스레드에서 유일하다 → 하나의 스레드 안에서 유일하다 O 여러 스레드 사이에선 유일하지 않을수도 있음
프로세스에서 유일하다는 것은 실제로 하나의 스레드 안에서 유일할 뿐만 아니라 같은 프로세스에 속한 여러 스레드 사이에서도 유일하다는 것을 뜻한다.
- 프로세스 = 아예 다른 집
- 스레드 = 한 집 안의 여러 방
프로세스 싱글턴 ➔ 한 집에 냉장고는 하나. 다른 집은 다른 냉장고 있음.
스레드 싱글턴 ➔ 방마다 자기 전용 냉장고 하나씩 둘 수도 있음.
팩터리 패턴
- 단순 팩터리 패턴
단순 팩터리 패턴 기반의 팩터리 클래스에는 대부분 Factory로 끝나는 이름을 붙인다. (다 그런건 아님) 객체를 생성하는 메서드의 이름은 creaste에 생성될 클래스의 이름을 붙이는 것이 일반적이다. 이 밖에 getInstance(), createInstance(), newInstance() 등 다른 방식으로 붙이기도 하며, JavaString 클래스의 valueOf() 메서드 처럼 앞에 설명한 어떠한 방법에도 속하지 않는 방법을 사용하기도 한다. -p.277
팩터리 패턴을 잘 쓰진 않지만, 이런 식으로 애매한 네이밍 규칙이 있는지는 몰랐다.
- 팩터리 메서드 패턴
- 추상 팩터리 메서드 패턴
지피티가 말하는 추상 팩터리 패턴
→ 추상 팩터리 패턴은 제품군은 다르지만, 사용하는 인터페이스는 같을 때 여러 관련 객체들을 통일된 방식으로 생성하려고 쓴다.
public interface IConfigParserFactory {
IRuleConfigParser createRuleParser();
ISystemConfigParser createSystemParser();
// 새로운 유형의 parser를 확장할 수 있음
}
public class JsonConfigParserFactory implements IConfigParserFactory {
@Override
public IRuleConfigParser createRuleParser() {
return new JsonRuleConfigParser();
}
@Override
public ISystemConfigParser createSystemParser() {
return new JsonSystemConfigParser();
}
}
public class XmlConfigParserFactory implements IConfigParserFactory {
@Override
public IRuleConfigParser createRuleParser() {
return new XmlRuleConfigParser();
}
@Override
public ISystemConfigParser createSystemParser() {
return new XmlSystemConfigParser();
}
}
생각해보기 6.3.5
- 객체를 생성하는 메서드가 정적이어야 하는 이유와 코드 테스트 용이성에 어떤 영향을 미치는지?
객체가 생성되지 않았는데도, new가 아니라 다른 메서드로 객체를 생성해야 하기 때문에 정적 메서드여야 한다.
장점 단점
정적 팩터리 메서드 | 생성 통제, 테스트 시 Mock 넣기 쉬움, 인터페이스 유지 | 정적 메서드는 Mocking 힘듦, 확장/커스터마이징 어려움 |
DI 컨테이너의 설계와 구현
Java 언어로 간단한 DI 컨테이너를 구현하는 핵심은 설정 파일을 분석하고, 그 결괄르 기반으로 리플렉션을 통해 객체 생성을 생성하는 것이 전부다.
- 최소 프로토타입 설계
- 실행 엔트리 포인트 제공
- 설정 파일 분석
- 핵심 팩터리 클래스 설계
빌더 패턴
빌더 패턴과 팩터리 패턴의 차이
팩터리 패턴은 동일한 상위 클래스나 인터페이스를 상속하는 하위 클래스 그룹과 같이 유형은 다르지만 연관되어 있는 객체를 생성할 때 사용되며, 이때 어떤 유형의 객체를 생성할지는 미리 지정된 매개변수에 의해 결정된다. 반면 빌더 패턴은 동일한 유형의 복잡도가 높은 객체를 생성하는데, 이때 선택적인 매개변수를 설정하거나 사용자 정의를 통해 다른 객체를 생성한다.
프로토타입 패턴
정의
객체의 생성 비용이 비교적 크지만, 동일한 클래스 기반으로 생성된 차이가 그리 크지 않은 객체를 생성할 경우, 생성 시간을 절약하기 위해 기존 객체인 프로토타입을 사용하여 복사를 통해 새 객체를 생성한다. 이렇게 프로토타입을 기반으로 생성하는 방식을 프로토타입 패턴이라고 한다.