Using factory helper pattern for dependent components
Let's try another method for dependent objects using the Factory pattern. This design pattern is based on the GOF factory design pattern to create object instances by using a factory method. So this method actually centralizes the use of the new operator. It creates the object instances based on the information provided by the client code. This pattern is widely used in the dependency injection strategy.
TransferService using factory helper:
package com.packt.chapter1.bankapp.transfer; public class TransferService { private AccountRepository accountRepository; public TransferService() { this.accountRepository =
AccountRepositoryFactory.getInstance("jdbc"); } public void transferMoney(Account a, Account b) { accountRepository.transfer(a, b); } }
In the preceding code, we use the Factory pattern to create an object of AccountRepository. In software engineering, one of the best practices of application design and development is program-to-interface (P2I). According to this practice, concrete classes must implement an interface that is used in the client code for the caller rather than using a concrete class. By using P2I, you can improve the preceding code. Therefore, we can easily replace it with a different implementation of the interface with little impact on the client code. So programming-to-interface provides us with a method involving low coupling. In other words, there is no direct dependency on a concrete implementation leading to low coupling. Let's look at the following code. Here, AccountRepository is an interface rather than a class:
public interface AccountRepository{ void transfer(); //other methods }
So we can implement it as per our requirement, and it is dependent upon the client's infrastructure. Suppose we want an AccountRepository during the development phase with JDBC API. We can provide a JdbcAccountRepositry concrete implementation of the AccountRepositry interface, as shown here:
public class JdbcAccountRepositry implements AccountRepositry{ //...implementation of methods defined in AccountRepositry // ...implementation of other methods }
In this pattern, objects are created by factory classes to make it easy to maintain, and this avoids scattering the code of object creation across other business components. With a factory helper, it is also possible to make object creation configurable. This technique provides a solution for tight coupling, but we are still adding factory classes to the business component for fetching collaborating components. So let's see the DI pattern in the next section and look at how to solve this problem.