// 추상화된 결제 인터페이스
public interface PaymentGateway {
boolean processPayment(String paymentId, double amount);
void refundPayment(String paymentId, double amount);
}
// 결제 시스템 A의 어댑터
public class PaymentGatewayAAdapter implements PaymentGateway {
private PaymentGatewayA paymentGatewayA;
public PaymentGatewayAAdapter(PaymentGatewayA paymentGatewayA) {
this.paymentGatewayA = paymentGatewayA;
}
@Override
public boolean processPayment(String paymentId, double amount) {
// PaymentGatewayA의 API를 호출하여 결제 처리
return paymentGatewayA.pay(paymentId, amount);
}
@Override
public void refundPayment(String paymentId, double amount) {
// PaymentGatewayA의 API를 호출하여 환불 처리
paymentGatewayA.refund(paymentId, amount);
}
}
// 결제 시스템 B의 어댑터
public class PaymentGatewayBAdapter implements PaymentGateway {
private PaymentGatewayB paymentGatewayB;
public PaymentGatewayBAdapter(PaymentGatewayB paymentGatewayB) {
this.paymentGatewayB = paymentGatewayB;
}
@Override
public boolean processPayment(String paymentId, double amount) {
// PaymentGatewayB의 API를 호출하여 결제 처리
return paymentGatewayB.processTransaction(paymentId, amount);
}
@Override
public void refundPayment(String paymentId, double amount) {
// PaymentGatewayB의 API를 호출하여 환불 처리
paymentGatewayB.refundTransaction(paymentId, amount);
}
}
// 애플리케이션 코드
public class PaymentService {
private PaymentGateway paymentGateway;
public PaymentService(PaymentGateway paymentGateway) {
this.paymentGateway = paymentGateway;
}
public boolean processPayment(String paymentId, double amount) {
return paymentGateway.processPayment(paymentId, amount);
}
public void refundPayment(String paymentId, double amount) {
paymentGateway.refundPayment(paymentId, amount);
}
}
// 주문 처리를 위한 복잡한 서브 시스템
public class OrderProcessor {
public void validateOrder(Order order) {
// ...
}
public void processPayment(Order order) {
// ...
}
public void updateInventory(Order order) {
// ...
}
public void shipOrder(Order order) {
// ...
}
}
// 파사드 클래스
public class OrderFacade {
private final OrderProcessor orderProcessor;
public OrderFacade(OrderProcessor orderProcessor) {
this.orderProcessor = orderProcessor;
}
public void placeOrder(Order order) {
orderProcessor.validateOrder(order);
orderProcessor.processPayment(order);
orderProcessor.updateInventory(order);
orderProcessor.shipOrder(order);
}
}
// 클라이언트 코드
public class Client {
public static void main(String[] args) {
OrderProcessor orderProcessor = new OrderProcessor();
OrderFacade orderFacade = new OrderFacade(orderProcessor);
Order order = new Order();
// ... 주문 정보 설정
orderFacade.placeOrder(order);
}
}
// 은행 시스템의 복잡한 서브 시스템
public class AccountSystem {
public void createAccount(String accountNumber) {
// ...
}
public void closeAccount(String accountNumber) {
// ...
}
}
public class PaymentSystem {
public void processPayment(String accountNumber, double amount) {
// ...
}
}
public class LoanSystem {
public void applyForLoan(String accountNumber, double amount) {
// ...
}
}
// 파사드 클래스
public class BankingServiceFacade {
private final AccountSystem accountSystem;
private final PaymentSystem paymentSystem;
private final LoanSystem loanSystem;
public BankingServiceFacade(AccountSystem accountSystem, PaymentSystem paymentSystem, LoanSystem loanSystem) {
this.accountSystem = accountSystem;
this.paymentSystem = paymentSystem;
this.loanSystem = loanSystem;
}
public void createAccount(String accountNumber) {
accountSystem.createAccount(accountNumber);
}
public void closeAccount(String accountNumber) {
accountSystem.closeAccount(accountNumber);
}
public void processPayment(String accountNumber, double amount) {
paymentSystem.processPayment(accountNumber, amount);
}
public void applyForLoan(String accountNumber, double amount) {
loanSystem.applyForLoan(accountNumber, amount);
}
}
// 클라이언트 코드
public class Client {
public static void main(String[] args) {
AccountSystem accountSystem = new AccountSystem();
PaymentSystem paymentSystem = new PaymentSystem();
LoanSystem loanSystem = new LoanSystem();
BankingServiceFacade bankingServiceFacade = new BankingServiceFacade(accountSystem, paymentSystem, loanSystem);
String accountNumber = "1234567890";
bankingServiceFacade.createAccount(accountNumber);
bankingServiceFacade.processPayment(accountNumber, 1000.0);
bankingServiceFacade.applyForLoan(accountNumber, 10000.0);
bankingServiceFacade.closeAccount(accountNumber);
}
}
스프링에서 @Service 어노테이션을 사용하여 서비스 클래스를 정의하는 것은 파사드 패턴의 일종으로 볼 수 있다
보통 실무에서 해당 도메인뿐만아니라 다른 도메인 서비스까지 불러서
복합적으로 비즈니스로직을 처리하는데 이런게 다 퍼사드 패턴의 일종 아닐까?
// 도메인 모델
@Entity
public class User {
// ...
}
@Entity
public class Order {
// ...
}
// 도메인 서비스
@Service
public class UserService {
// ...
}
@Service
public class OrderService {
// ...
}
// 리포지토리
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
// ...
}
@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
// ...
}
// 애플리케이션 서비스 (파사드)
@Service
public class UserOrderFacade {
private final UserService userService;
private final OrderService orderService;
public UserOrderFacade(UserService userService, OrderService orderService) {
this.userService = userService;
this.orderService = orderService;
}
public void createUserAndOrder(User user, Order order) {
userService.createUser(user);
orderService.createOrder(order);
// 추가 비즈니스 로직 처리
}
public List<Order> getOrdersByUser(User user) {
// 사용자의 주문 목록 조회 로직
}
}