4. 추가 패턴 (Additional Patterns)
추가 패턴은 생성, 구조, 행위 패턴에 포함되지 않는 특수한 목적의 디자인 패턴이다.
이 패턴들은 특정 상황에서 문제를 해결하거나, 성능을 최적화하는 데 유용하게 사용된다.
---
4.1 Null Object Pattern (널 객체 패턴)
개념:
객체가 null인 경우, null 체크를 하지 않고도 정상적인 동작을 수행할 수 있도록 기본 객체를 제공하는 패턴.
구조 다이어그램:
+------------+
| Object |
+------------+
|
+---------+--------+
| |
+-------+ +---------+
| Real | | Null |
|Object | | Object |
+-------+ +---------+
예제 코드:
interface Animal {
void makeSound();
}
class Dog implements Animal {
public void makeSound() {
System.out.println("Bark");
}
}
class NullAnimal implements Animal {
public void makeSound() {
System.out.println("No animal found.");
}
}
class AnimalFactory {
public static Animal getAnimal(String type) {
if ("Dog".equalsIgnoreCase(type)) {
return new Dog();
}
return new NullAnimal();
}
}
public class Main {
public static void main(String[] args) {
Animal dog = AnimalFactory.getAnimal("Dog");
Animal unknown = AnimalFactory.getAnimal("Cat");
dog.makeSound();
unknown.makeSound();
}
}
출력:
Bark
No animal found.
장단점:
장점: null 체크를 줄여 코드 가독성 향상
단점: 모든 경우에 null 객체를 정의해야 하므로 코드가 늘어날 수 있음
---
4.2 Dependency Injection Pattern (의존성 주입 패턴)
개념:
객체가 필요로 하는 의존성을 외부에서 주입받는 방식으로 객체 간의 결합을 줄이는 패턴.
구조 다이어그램:
+-----------+
| Client |
+-----------+
|
+-----------+
| Service |
+-----------+
예제 코드:
interface Service {
void execute();
}
class EmailService implements Service {
public void execute() {
System.out.println("Sending email...");
}
}
class Notification {
private Service service;
public Notification(Service service) {
this.service = service;
}
public void notifyUser() {
service.execute();
}
}
public class Main {
public static void main(String[] args) {
Service emailService = new EmailService();
Notification notification = new Notification(emailService);
notification.notifyUser();
}
}
출력:
Sending email...
장단점:
장점: 객체 간의 결합을 줄여서 테스트 용이성 향상
단점: 코드가 분리되면서 초기화 과정이 복잡해질 수 있음
---
4.3 Lazy Initialization Pattern (지연 초기화 패턴)
개념:
객체의 초기화 비용이 클 경우, 실제로 필요할 때까지 객체 생성을 지연시키는 패턴.
구조 다이어그램:
+-----------+
| Singleton |
+-----------+
|
+-----------+
| Instance |
+-----------+
예제 코드:
class HeavyObject {
public HeavyObject() {
System.out.println("Heavy object created.");
}
}
class LazyInitializer {
private HeavyObject heavyObject;
public HeavyObject getInstance() {
if (heavyObject == null) {
heavyObject = new HeavyObject();
}
return heavyObject;
}
}
public class Main {
public static void main(String[] args) {
LazyInitializer initializer = new LazyInitializer();
System.out.println("Object not created yet.");
initializer.getInstance();
initializer.getInstance();
}
}
출력:
Object not created yet.
Heavy object created.
장단점:
장점: 메모리 절약, 불필요한 객체 생성을 방지
단점: 멀티스레딩 환경에서 동기화 처리가 필요할 수 있음
---
4.4 Extension Object Pattern (확장 객체 패턴)
개념:
객체에 새로운 기능을 추가할 때, 기존 클래스를 수정하지 않고 확장 객체를 통해 기능을 추가하는 패턴.
구조 다이어그램:
+----------+
| Client |
+----------+
|
+----------+
| Object |
+----------+
|
+----------+
| Extension |
+----------+
예제 코드:
interface Extension {
void extend();
}
class BasicObject {
void operation() {
System.out.println("Basic Operation");
}
}
class ExtensionA implements Extension {
public void extend() {
System.out.println("Extension A");
}
}
class ExtensionB implements Extension {
public void extend() {
System.out.println("Extension B");
}
}
public class Main {
public static void main(String[] args) {
BasicObject object = new BasicObject();
object.operation();
Extension extA = new ExtensionA();
extA.extend();
Extension extB = new ExtensionB();
extB.extend();
}
}
출력:
Basic Operation
Extension A
Extension B
장단점:
장점: 기존 클래스의 코드를 변경하지 않고 확장 가능
단점: 확장 객체가 많아질 경우 관리가 어려워질 수 있음
---
4.5 Double-Checked Locking Pattern (이중 검사 잠금 패턴)
개념:
멀티스레드 환경에서 객체의 인스턴스를 한 번만 생성하도록 보장하는 패턴.
첫 번째 검사에서 인스턴스가 null인지 확인하고, 두 번째 검사에서 동기화 블록 내에서 객체를 생성한다.
구조 다이어그램:
+-----------+
| Singleton |
+-----------+
|
+-----------+
| Instance |
+-----------+
예제 코드:
class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
public class Main {
public static void main(String[] args) {
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s1 == s2);
}
}
출력:
true
장단점:
장점: 객체 생성 비용 절감, 멀티스레드 안전성 보장
단점: 코드가 복잡해질 수 있으며, Java 1.4 이전 버전에서는 문제가 발생할 수 있음
'Learning > .programming' 카테고리의 다른 글
[디자인 패턴] 2) 구조 패턴 (0) | 2025.05.18 |
---|---|
[디자인 패턴] 3) 행위 패턴 (0) | 2025.05.18 |
[디자인 패턴] 1) 생성 패턴 (0) | 2025.05.18 |
[오토핫키 AutoHotKey] 컴퓨터 켤 때 자동 실행시키기 (0) | 2022.09.12 |
[오토핫키 AutoHotKey] 방향키 리맵핑 스크립트 (Alt, CapsLock) (0) | 2022.09.12 |
[오토핫키 AutoHotKey] 설치 & Script 파일 만들기 (0) | 2022.09.12 |
[오토핫키 AutoHotKey] 방향키 리맵핑하기 (Alt, CapsLock) (0) | 2022.09.12 |
[AWS 프리티어 종료 후 과금] 인스턴스 종료, 환불문의, 계정탈퇴 (0) | 2022.04.03 |