I’ve finished Effective Java book and after it I got confused. In this book Bloch insist on decreasing mutability, making fields final, refuse public constructors and favor factories or builder pattern, disabling inheritance using final classes and methods and etc.
But right now I’m working on a project based on Spring framework and:
- All entities must have default constructor (Spring Data JPA)
- All services should be non-final to mock them
- All classes must be non-final to have a chance to be advised (Spring AOP, AspectJ)
At the first blush seems that most part of the book is violated by AOP, mocking and by Spring Data/Hibernate.
How should I deal with it? Is the book useless in practice?
Effective Java describes general best practices that better be followed when it's possible. But it considers pure java, not any framework features.
Framework defines the architecture of the project and you should follow these rules. It has it's own best practices.
Immutable objects are good because they are inherently thread-safe; their invariants are established by the constructor, and if their state cannot be changed, these invariants always hold. But there is no strict rule that every object should be immutable, sometimes it is not possible in scope of the given task.
Builders and factory patterns are still good and could be used in scope of a
Spring project. I used both Spring dependencies and Factory patterns in real project, because Factory still allows you to
As an overal example, I used Spark functions in Spring project. Some of the functions were
@Autowire Spring services. But the functions themselfes were not Spring services. You cannot create them by
new Function() because then Spring will be not able to autowire the Service. But with Factory, you can help Spring to do so.
There are many good design principles like
SOLID, DRY, KISS, design patterns which are usually helpful and allow you organize the code much better. But sometimes, in real life, you simple just cannot apply all of them to your particullar case. The main rule here is that you should not absolutize any of best practices and find a middle ground between achievement of final goal and applying the best practices.