-
자주 사용되는 디자인 패턴에 대해 알아보자 (springboot)Server/Spring Boot 2025. 4. 28. 17:44728x90반응형
Spring Boot 개발에서 꼭 알아야 할 디자인 패턴
1. 싱글턴 패턴 (Singleton Pattern)
싱글턴 패턴은 객체를 하나만 생성하여 모든 클라이언트가 동일한 인스턴스를 공유하도록 하는 패턴입니다. Spring에서는 주로 @Service, @Component, @Repository 등의 어노테이션을 사용하여 빈을 생성할 때 싱글턴을 기본으로 사용합니다.
import org.springframework.stereotype.Service; @Service public class SingletonService { private static SingletonService instance; private SingletonService() {} public static SingletonService getInstance() { if (instance == null) { instance = new SingletonService(); } return instance; } public String getMessage() { return "싱글턴 패턴 예제!"; } }
설명: SingletonService 클래스는 getInstance() 메서드를 통해 객체를 한 번만 생성하고, 그 후에는 동일한 인스턴스를 반환합니다.
2. 전략 패턴 (Strategy Pattern)
전략 패턴은 알고리즘을 클래스화하여 각각의 전략을 교환 가능하게 만드는 패턴입니다. Spring에서는 비즈니스 로직을 다양한 전략 객체로 나누어 사용하는 경우가 많습니다.
// 전략 인터페이스 public interface PaymentStrategy { void pay(); } // 콘크리트 전략 1 public class CreditCardPayment implements PaymentStrategy { @Override public void pay() { System.out.println("신용카드로 결제"); } } // 콘크리트 전략 2 public class PaypalPayment implements PaymentStrategy { @Override public void pay() { System.out.println("PayPal로 결제"); } } // Context public class PaymentService { private PaymentStrategy paymentStrategy; public PaymentService(PaymentStrategy paymentStrategy) { this.paymentStrategy = paymentStrategy; } public void executePayment() { paymentStrategy.pay(); }
설명: PaymentService 클래스는 PaymentStrategy 인터페이스를 통해 결제 방법을 선택할 수 있게 하며, 필요에 따라 결제 전략을 변경할 수 있습니다.
3. 팩토리 패턴 (Factory Pattern)
팩토리 패턴은 객체를 생성하는 인터페이스를 제공하고, 구체적인 클래스의 인스턴스는 서브클래스에서 결정하도록 하는 패턴입니다. Spring에서는 빈을 자동으로 생성할 때 팩토리 메서드 방식이 많이 사용됩니다.
// 팩토리 인터페이스 public interface Vehicle { void drive(); } // 콘크리트 제품 1 public class Car implements Vehicle { @Override public void drive() { System.out.println("자동차를 운전"); } } // 콘크리트 제품 2 public class Bike implements Vehicle { @Override public void drive() { System.out.println("자전거를 타기"); } } // 팩토리 클래스 public class VehicleFactory { public Vehicle createVehicle(String type) { if ("car".equalsIgnoreCase(type)) { return new Car(); } else if ("bike".equalsIgnoreCase(type)) { return new Bike(); } return null; } }
설명: VehicleFactory 클래스는 createVehicle() 메서드를 통해 조건에 맞는 객체를 생성하여 반환합니다.
4. 옵저버 패턴 (Observer Pattern)
옵저버 패턴은 한 객체의 상태 변화가 있을 때, 그것을 의존하고 있는 객체들에게 자동으로 알리는 패턴입니다. Spring에서는 ApplicationEventPublisher를 활용하여 이벤트 리스너 패턴을 구현할 때 사용됩니다.
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.stereotype.Component; @Component public class UserService implements ApplicationEventPublisherAware { private ApplicationEventPublisher publisher; @Override public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { this.publisher = publisher; } public void createUser(String username) { System.out.println("사용자 생성: " + username); publisher.publishEvent(new UserCreatedEvent(this, username)); } } public class UserCreatedEvent extends ApplicationEvent { private String username; public UserCreatedEvent(Object source, String username) { super(source); this.username = username; } public String getUsername() { return username; } } @Component public class UserCreatedEventListener { @EventListener public void onUserCreated(UserCreatedEvent event) { System.out.println("새로운 사용자 생성됨: " + event.getUsername()); } }
설명: UserService는 새로운 사용자가 생성될 때 UserCreatedEvent 이벤트를 발행하고, UserCreatedEventListener는 이를 구독하여 알림을 받습니다.
5. 데코레이터 패턴 (Decorator Pattern)
데코레이터 패턴은 객체에 새로운 기능을 동적으로 추가할 수 있는 패턴입니다. Spring에서는 주로 AOP(Aspect-Oriented Programming)에서 사용되며, 메서드 실행 전후에 추가적인 작업을 할 때 사용됩니다.
public interface Coffee { double cost(); } public class SimpleCoffee implements Coffee { @Override public double cost() { return 5.0; } } public class MilkDecorator implements Coffee { private Coffee decoratedCoffee; public MilkDecorator(Coffee coffee) { this.decoratedCoffee = coffee; } @Override public double cost() { return decoratedCoffee.cost() + 1.5; } } public class SugarDecorator implements Coffee { private Coffee decoratedCoffee; public SugarDecorator(Coffee coffee) { this.decoratedCoffee = coffee; } @Override public double cost() { return decoratedCoffee.cost() + 0.5; } }
설명: SimpleCoffee 객체에 MilkDecorator와 SugarDecorator를 추가하여 커피의 비용을 동적으로 변경할 수 있습니다.
결론
위에서 소개한 디자인 패턴들은 Spring Boot 애플리케이션에서 자주 사용되는 패턴들이며, 이를 통해 코드의 재사용성, 유지보수성 및 확장성을 높일 수 있습니다.
728x90반응형'Server > Spring Boot' 카테고리의 다른 글
Spring Boot에서 많이 사용되는 View 엔진 추천 및 장단점 (0) 2025.04.29 [Springboot] 인증(Authentication)과 인가(Authorization) 구분하기! (0) 2025.04.21 [Springboot] SQL Injection 이란? 해결 방안은? (0) 2025.04.21 [Springboot] 통합 테스트 코드 작성해보기 (Controller) (1) 2025.04.21 [Springboot] 단위 테스트 코드 작성해보기 (Service, Dao, Repository) (0) 2025.04.21