본문 바로가기
Programming/Java

JAVA의 개발 디자인 패턴들 : 싱글턴, 팩토리 메소드

by Devsaurus 2024. 1. 10.
728x90

Singleton Pattern

클래스에 인스턴스가 하나만 있는지 확인하고 이에 대한 전역 액세스 지점을 제공합니다.

public class Singleton {
    private static Singleton instance;

    private Singleton() {
        // Private constructor to prevent instantiation
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

 

사용 예

Singleton singleton = Singleton.getInstance();

 

Factory Method Pattern

객체를 생성하기 위한 인터페이스를 정의하되, 생성될 객체의 유형을 하위 클래스에서 변경할 수 있도록 합니다.

public interface Product {
    void create();
}

public class ConcreteProduct implements Product {
    @Override
    public void create() {
        System.out.println("Creating ConcreteProduct");
    }
}

public interface Creator {
    Product factoryMethod();
}

public class ConcreteCreator implements Creator {
    @Override
    public Product factoryMethod() {
        return new ConcreteProduct();
    }
}

 

사용 예

Creator creator = new ConcreteCreator();
Product product = creator.factoryMethod();

Observer Pattern

 

한 개체의 상태가 변경되면 해당 개체의 모든 종속 개체에 알림이 전달되고 자동으로 업데이트되도록 개체 간의 일대다 종속성을 정의합니다.

import java.util.ArrayList;
import java.util.List;

public interface Observer {
    void update(String message);
}

public class ConcreteObserver implements Observer {
    private String name;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name + " received message: " + message);
    }
}

public class Subject {
    private List<Observer> observers = new ArrayList<>();

    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    public void notifyObservers(String message) {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}

 

사용 예

Subject subject = new Subject();
Observer observer1 = new ConcreteObserver("Observer1");
Observer observer2 = new ConcreteObserver("Observer2");

subject.addObserver(observer1);
subject.addObserver(observer2);

subject.notifyObservers("Hello, observers!");

 

프로젝트의 예

웹 애플리케이션 프로젝트에서는 전략 패턴을 적용하여 다양한 인증 전략을 구현했습니다. 

시스템은 다양한 인증 방법(예: 사용자 이름/비밀번호, OAuth, API 키)을 지원해야 했습니다. 

각 인증 방법은 공통 AuthenticationStrategy 인터페이스를 구현하는 별도의 전략 클래스에 캡슐화되었습니다. 

런타임 시 전략을 쉽게 전환할 수 있었고 기존 코드베이스를 수정하지 않고도 새로운 인증 방법을 추가할 수 있었습니다.

public interface AuthenticationStrategy {
    void authenticate();
}

public class UsernamePasswordAuthentication implements AuthenticationStrategy {
    @Override
    public void authenticate() {
        // Implementation for username/password authentication
    }
}

public class OAuthAuthentication implements AuthenticationStrategy {
    @Override
    public void authenticate() {
        // Implementation for OAuth authentication
    }
}

public class AuthenticationContext {
    private AuthenticationStrategy strategy;

    public void setAuthenticationStrategy(AuthenticationStrategy strategy) {
        this.strategy = strategy;
    }

    public void authenticateUser() {
        strategy.authenticate();
    }
}

 

이 설계를 통해 기존 코드를 수정하지 않고도 인증 방법을 쉽게 확장할 수 있어 애플리케이션 인증 모듈의 유연성과 유지 관리성이 향상되었습니다.

728x90