Many people know the Model View Controller architectural pattern. Another interesting pattern is Presentation Abstraction Control architectural pattern. We can implement it using Dependency Injection or similar Inversion of Control patterns. So, when we are modeling solutions, we many times leave the control or business logic on the Controller. This will guide us to a very coupled platform. Remember that any well designed architecture claims for cohesion instead of coupling its components. On this article I will try to analyze the use of IoC on the PAC pattern, so we can have more maintainable software components, mainly on n-tier architectures.
control classes and interfaces
We can hold our business logic on separate classes. As example we will use a bank loan application, which is supposed to bring us the proper load for certain kind of customers of a bank. So, we need to define an interface pf the loan component.
interface Loan { void setUserData(User bankUser); void setCustomerData(Customer cus, Account acc); LoanResults getLoanResults(); }
This simple interface should be implemented by a variety of Loan types, from consumer ones to mortgage ones, since this variety of loans have different evaluation and estimation logic.
Now we need to define a way to instantiate the proper Loan implementation. The proper Loan implementation request is on the hands of the control layer, since the Loan interface is the abstraction layer itself. So, if we have to need the same methods for every Loan that we request, we just use a Factory Pattern returning the interface Loan, instead of his real implementation.
the abstraction layer
The abstraction layer is implemented on the Loan interface and its returning implementation based on the factory pattern. So we need to implement the factory outside of the package that holds that set of interfaces and implementations. The factory also hold the logic that decides which Loan implementation will be returned, based on the user data, customer data and account data. So we need a call similar to this one:
Loan loanRequest = LoanFactory.getInstance(data); LoanResults requestResults = loanRequest.getLoanResults();
So, the factory and the loan interface holds the abstraction layer, separating the decoupling the business logic from its real implementation and generating more cohesion. What does the loan request form in the application about those components? The answer is quiet simple: nothing. We will use another pattern to hold input data and pass it through the abstraction layer from the presentation layer. Here is when we are doing dependency injection.
the presentation layer
The presentation layer, which in this case holds a simple LoanRequestForm will never know which concrete class will be used to deliver the LoanResults, so we have to define an instance of another pattern, an Adapter. The adapter should transform the input data from the LoanRequestForm to some kind of Data Transfer Object, to be passed to the factory as CustomerData.
class LoanRequestForm { protected Customer cus; protected User usr; protected Account acc; protected LoanRequestFormAdapter adapter = new LoanRequestFormAdapter(); protected Loan loanRequest; LoanResults getLoanResults() { try { loanRequest = LoanFactory.getInstance(adapter.transform(this)); LoanResults requestResults = loanRequest.getLoanResults(); return requestResults; } catch (InvalidDataException ex) { log.error(ex); } } }
Here we are injecting a dependency for the LoanRequestForm and also we acquiring abstraction through the LoanFactory, transforming its input using the LoanRequestFormAdapter to transform the form data into a DTO (Data Transfer Object). The business logic is completely separated from the its User Interface and the abstraction layer. So we are fitting the model with PAC pattern and the IoC DI pattern at once.
The transformation between the form and the factory is a must. The factory can not depend on the form and the form can not depend on the factory. The adapter plays an important role here, since it’s separating layers and transforming the application into an n-tier architected application, so we have more control over changes and possible enhancements on the model. Also it will bring us possible automated processes, since the factory do not needs the form to operate over the loan. So you build another application that just handles the user data and generate loan bids automatically to the customers based on the same logic, then we are reusing the properly the code.
conclusion
We can glue the PAC pattern with IoC DI pattern, so we have more reliable and flexible GUI implementations, then we can work in our platforms without worries about how to generate reusable code if we follow well designed and well applied patterns. Also we can use frameworks, but it depends on the application size and how do need to work on it. For an application with just two active forms, we do not need large scale architectures.