28
Jan
2025
0

FACTORY

Factory design pattern is used when we have a superclass with multiple subclasses and based on the input, we need to return one of the subclasses. This pattern removes the responsibility of instantiating a class from the client program to the factory class. The case addressed was for the creation of a practice that could be created differently depending on the user role. The approach was to create various classes depending on the user role and then instantiate the class based on the role in the factory.

Implementing the Factory Pattern in Spring

Let’s illustrate the Factory pattern with a fun example we’ll start with a simple explanation.

Overall, the hierarchy of classes that have been implemented therefore becomes the one shown in the following figure.

Step 1: Create the Class

@Component
public class PracticeFactory {

@Autowired
@Qualifier("ciCompanyDecoratorService")
private IPracticesService ciCompanyDecoratorService;

@Autowired
@Qualifier("ciIntermDecoratorService")
private IPracticesService ciIntermDecoratorService;

@Autowired
@Qualifier("ciRegDecoratorService")
private IPracticesService ciRegDecoratorService;

public PracticeFactory(IPracticesService ciCompanyDecoratorService,
                       IPracticesService ciIntermDecoratorService, 
                       IPracticesService ciRegDecoratorService) {

   this.ciCompanyDecoratorService = ciCompanyDecoratorService;
   this.ciIntermDecoratorService = ciIntermDecoratorService;
   this.ciRegDecoratorService = ciRegDecoratorService; 
}

public IPracticesService getService(EnumUser user) {

   IPracticesService iPracticesService = null;
   switch (user) {
      case COMPANY: {
         iPracticesService = ciCompanyDecoratorService;
         break;
      }
      case INTERMEDIARY: {
         iPracticesService = ciIntermDecoratorService;
         break;
      }
      case REGIONAL: {
         iPracticesService = ciRegDecoratorService;
         break;
      }
      default:
         throw new IllegalArgumentException("Unexpected value: " + user.getCode());
      }
   return iPracticesService;
}

Step 2: Using the Factory

@SpringBootApplication
public class DemoApplication implements CommandLineRunner {

@Autowired
private PracticeFactory factory;

public static void main(String[] args) {
   SpringApplication.run(DemoApplication.class, args);
}

@Override
public void run(String... args) throws Exception {
   IPracticesService serviceFactory = factory.getService(EnumUser.COMPANY);
   System.out.println("User to call function company");
   serviceFactory.validPractice(new PracticeDTO()); 
   serviceFactory.updatePractice(new PracticeDTO());
   serviceFactory.saveDraft(new PracticeDTO());
   serviceFactory.saveStatusPractice(Long.getLong("123456"), "ACTIVE");
   System.out.println("");
   System.out.println("User to call function intermediary");
   serviceFactory = factory.getService(EnumUser.INTERMEDIARY);
   serviceFactory.validPractice(new PracticeDTO()); 
   serviceFactory.updatePractice(new PracticeDTO());
   serviceFactory.saveDraft(new PracticeDTO());
   serviceFactory.saveStatusPractice(Long.getLong("123456"), "NO ACTIVE");
   System.out.println(""); 
   System.out.println("User to call function regional");
   serviceFactory = factory.getService(EnumUser.REGIONAL);
   serviceFactory.validPractice(new PracticeDTO()); 
   serviceFactory.updatePractice(new PracticeDTO());
   serviceFactory.saveDraft(new PracticeDTO());
   serviceFactory.saveStatusPractice(Long.getLong("123456"), "ENDED");
   System.out.println("");
}

In this example, we have a PracticeFactory class, that for every role of user return a specific instance of service for different role.

Conclusion

The Factory pattern removes instantiation of the actual implementation classes from client code. The Factory pattern makes our code more robust, less coupled, and easier to extend. For example, we can easily change the implementation of the PC class because the client program is unaware of it. Here you can found code example.

You may also like

DECORATOR
STRATEGY
Design Pattern in spring