nanachimi nanachimi - 3 years ago 53
Java Question

Factory Pattern when Constructor of the Implementation has Dependencies to Inject

I'm working on a private stuff and I faced an issue where I need other opinion. I have the following code where I want to make a factory pattern the create new instance of

PaymentStrategy
:

PaymentStrategy
interface



public interface PaymentStrategy {

Optional<Payment> pay(String payerAccountNumber,
String sellerAccountNumber,
ProductOrder[] productOrder
);
}


EmployeePaymentStrategy
implementation which has two dependencies



public class EmployeePaymentStrategy implements PaymentStrategy {

private final ProfileRemoteProvider profileRemoteProvider;
private final PaymentValidator paymentValidator;

@Autowired
public EmployeePaymentStrategy(ProfileRemoteProvider profileRemoteProvider,
PaymentValidator paymentValidator) {
this.profileRemoteProvider = profileRemoteProvider;
this.paymentValidator = paymentValidator;
}

@Override
public Optional<Payment> pay(String payerAccountNumber,
String sellerAccountNumber,
ProductOrder[] productOrder) {
...
}
}


I want to know how to deal with dependencies in a Factory class.
Is the
EmployeePaymentStrategy
class the right place to inject those two dependencies?
Is the Factory Pattern is best way to solve problem

PaymentStrategyFactory
where I have the issue



public class PaymentStrategyFactory {

private PaymentStrategyFactory() {
}

public static PaymentStrategy getPaymentStrategy(AccountType payerAccountType,
AccountType sellerAccountType) {
if (sellerAccountType == AccountType.COMPANY) {
switch (payerAccountType) {
case EMPLOYEE:
return new EmployeePaymentStrategy(...); //TODO
case BASIC_USER:
return ...
default:
//this exception is throw when a payer account type is unknown
throw new RuntimeException("exception type will be more specific");
}
}
//This exception is throw when a seller account type is not a seller
throw new RuntimeException("exception type will be more specific");
}
}

Answer Source

PaymentStrategyFactory UPDATED and WORKING

public class PaymentStrategyFactory {

  private static ApplicationContext context;
  private ApplicationContext applicationContext;

  @Autowired
  private PaymentStrategyFactory(ApplicationContext applicationContext) {
    this.applicationContext = applicationContext;
  }

  @PostConstruct
  private void initializeApplicationContext() {
    PaymentStrategyFactory.context = applicationContext;
    this.applicationContext = null;
  }

  @Override
  public void setApplicationContext(ApplicationContext context) throws BeansException {
    PaymentStrategyFactory.context = context;
  }

  public static PaymentStrategy getPaymentStrategy(AccountType payerAccountType,
                                                   AccountType sellerAccountType) {
    if (sellerAccountType == AccountType.COMPANY) {
      switch (payerAccountType) {
        case EMPLOYEE:
          return context.getBean(EmployeePaymentStrategy.class);
          // return new EmployeePaymentStrategy();
        case BASIC_USER:
           ...
        }
     } 
     throw ...
   }
}

Additionally to the comment of Ilya below, this post help me to deal with static member when using Spring for DI (Dependencies Injection). Now everything look fine for me.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download