Pure OO, Inversion of Control(IoC) + Dependency Injection(DI) and The Cake Pattern(FP): Whats really matters?12:31:00 AM
In this post i want cover something if you was java developer was the central idea around java development for years.
Spring Framework dominate the fields for more than a decade. The real question is not if you should be using XML or annotations(like Guice).
Either if you should go XML or java Annotations. Thats kind of old discussion, so basically what are the options now a days?
So it`s all about software design, you can do a bunch of stuff now a days, depending of your language you have more or less options even if your language dont provide plenty of options and syntax sugar like Scala you can do some interesting stuff. So the Options Are:
1. Pure OO, no IOC/DI whatsoever
2. Classical IOC/DI with Spring(xml) or annotations (Spring 2.5+ or Guice).
3. Cake Pattern if you are on java 8 or Scala for instance
4. Function Composition with Protocols if you are from clojure.
Why Care about it anyways? Let`s see the design problem!
In this code we are doing a very simple toll service, so you need to decide how much tax you gonna charge for a specific car. I`m not trying to argue here on OVER-DESIGN because you can always be agile and refactor you code when you needed.
So on the Brazilian Toll Service we have basically 3 problems, 1 is the fact the is being instantiated by the code directly on the Toll class and this will make it hard to test and to change the service if needed. 2 problem is the fact we dont have an interface for the TollService making hard to extend the code and add different / new behavior. And 3 this code is all fixed so you dont have any option to configure the application and modify how it work or extend it.
Fixing this with #1 Pure OO
You will do 3 things basically.
1. Create a interface for TaxService and make the BrazillianTollService implement it, this will laverage the level of abstraction.
2. You wont instanciate the BrazillianTollService directly you will receive by code.
3. You will need have setter so the code can have options, this means if you want set a different implementation you can since you dealing with interfaces everywhere.
This solution goes on pure OO Design this makes the code better and easy to test.
With this code if you want you can do the solution #2, just add the Spring or Guice. They will make things easier with Annotations or XML but that dont change the fact you gonna need to have this design.
Thats all about frameworks inset? They keep putting you into a frame, a direction in this case: Spring/Guice are great because they kinda of make you do a little better design and by the ways is totally testabled and easier to refactor :-)
#3 The Cake Pattern
This is the Scala(Functional Programing) and the new way to deal with this design problem, so if you want there is this great posts that explain with more details in here:
Basically you can see this as a onin, there are some layers, so you dont access things directly, similar to Ioc. You can see this as bunch of Wrappers and Callbacks, so lets see how we do this? Basically you will need traits.
The TaxRepository is our previous TaxService interface but im using the default names that the cake patterns demands just to make more sense. Them we need a kind of service locator, so as you can see is the TaxRepositoryComponent that also what we call a Getter of Getters in functional programing, its what in oo you would call a Factory.
Them the TaxService because a Wrapper just delegate the code to the Repository. WE also need binf this 2 things, thats hwy we have the TaxServiceComponent this class just pass the repository to the service and here we have our first trait in java 8 using the default method on the interface.
The BrazillianTollService comes on the sequence as you can see he implements the previous interrface and override the default method providing the real implementation, the code gets a little noise and kinda of old inner-ish like but it not that hard to get it.
Last we create the LocalApp is the concrete class who implements TaxServiceComponent and BrazillianTollService here is me doing what we call in Scala and Groovy and Mixin! In Scala you would do mixins with traitis using the operator *with*.
So you got all previous befefits but without Spring/Guice and just code. This is coll but it generates more code than just uses spring, scala would be the same thing, but since scala has better sugar than Java 8 you would not notice all this code.
See, same thing, but better syntax. The problem of this is that you crate more code, for each thing you need to have a trait + class(Getter of Getters) in classical IoC Spring or Guice are the factory so you cut this things by half.
The great thing here is you can do all by code and becomes easier to read.
So Whats the Point?
No matter if you are doing Java OO, Plain OO, Functional Programing with Scala or Java 8, your code will need to have a good Design and ways to deal with system wide configuration. Spring/Guice are great to expose and manage configuration and also extensibility(but thats the design mostly).
So IoC/DI still matter? Yes they do, buscase even doing cake pattern is a different way to address same concerns as: Tests, Good Design, Extensibility and Configuration system wide. For me using a cacke pattern in scala / java 8 or IoC/DI with Spring/Guice is a matter of choise because we can archive the same results. In scala IoC/DI is less relevant tham in java because is scala is a haskell children and most of things are done by compilation so the code is your kinda of middleware, in java is more important since most of stuff is performed at runtime. But as i said is more like a personal choise.