1

I was watching a presentation by Uncle Bob. In the end of that presentation (last 10 min), He argued that we should abstract everything (Even frameworks) from our business logic.

JAVA EE does a great job in doing so. UI is abstracted by JSF (and other technologies). The database is abstracted by the persistence layer (JPA), even IOC container (Framework) can be abstracted by using standard annotations (CDI).

So far so good, but some frameworks completely ignore CDI and introduce their own Annotations (Bad sign! they are trying to couple their framework to our code). How we can prevent it. Uncle Bob's advice is to limit the use of Dependency Injection in our code and use other patterns such as Factory method, ...

But I think it is not a feasible approach for example for Dependency Injection we need to implement Service locator pattern (re inventing the Well) we can't have the functionality that frameworks provide (life cycle callbacks, ...).

Any thoughts ??

  • What's the problem with implementing frameworks and make them to do the heavy lifting? I mean, why is It a problem? If there's any and it's counterproductive, why to use It at all? – Laiv Feb 25 at 17:37
  • it is all about separating your business logic (the goal of your program from) from all the rest on the things (communication media, storage mechanism, even frameworks). – Mr.Q Feb 25 at 18:11
  • That is relatively easy to do with the right encapsulation. I fail at see the problem. The whole architecture can be implemented in one project while business and domain can be implemented elsewhere. It's up to you to decide how deep FWs root in your architecture. – Laiv Feb 25 at 18:41
  • could you elaborate? For example, when you want to use DI framework in your product (project), in an abstract way, you have two options: one is to create an abstract layer over your DI framework which according to "@David Arno" may not lead to a good result. OR you can use patterns like (factory, service locator) to mimic that behavior and loose the DI frameworks with all their benefits and drawbacks – Mr.Q Feb 26 at 5:13
  • 2
    As always, take whatever Robert Martin says with a grain of salt. Some of his advice is good, but the way he blanket stuff in a "one true way" is an extreme disservice to the software development community. – T. Sar Feb 26 at 13:44
5

The easiest way to avoid dependencies on a framework is to not use a framework.

Abstracting frameworks just doesn't work in practice. For example Microsoft tried creating an abstraction over their MVC Di framework and it caused way more problems than it solved. Abstractions add complexity, always. Therefore there has to be a benefit to that added complexity. An abstraction that stifles innovation (ie you regard introducing new annotations as a "Bad sign!"), panders to the lowest common denominator and - invariably - leaks implementation details of the "baseline" implementation isn't adding benefit.

Even the likes of Java EE, which has a good abstraction model, allowing more than one implementation to implement it, still heavily restrict you. If you adopt Java EE, you couple yourself to that abstraction; you still aren't free to do things another way easily. Java EE is still basically a framework and you still couple yourself to that framework once chosen.

So what can you do? Don't use frameworks, especially for things like DI. Use pure DI, inject factories as "Uncle Bob" suggest etc. Keep your DI model simple and you don't need a framework to handle it for you. Or if you must have a framework, view it like picking a programming language: go with one you like and stick with it until it no longer meets your needs, and don't fall into the trap of trying to create an abstraction around it.

  • nice point you mentioned about not wrapping Di framework under another abstraction layer. DI frameworks provide lots of functionalities that can't be easily ignored. I guess Uncle Bob is too idealistic in this regard :) – Mr.Q Feb 25 at 18:46
  • 3
    A good point from a tutor from the past: more often than not, the DI you need is far simpler than the DI you end up using if you use a DI Framework. Don't using a DI Framework is a very sensible advice, and I can't upvote this question enough. – T. Sar Feb 26 at 13:47
  • The problem comes with frameworks that do everything plus DI. It would be hard to don't use frameworks that boost productivity. Take Spring. DI is the less of the problem if you miss such a framework. What about things like configuration, security, transaction management, parametrization, integrations! As usual, the key is to choose the right tool for the right job for the moment. Picking a framework should not be a matter of fashions or trends. Like any other thing in this profession, it's a matter of balancing trade-offs. – Laiv Feb 26 at 14:20
1

Since you tagged Spring I'll answer based on that, because I have no idea how much you can applied it to others framework but it's likely most of all is doable with others framework.

In Spring you can isolate the dependency management by instantiating your classes in the @Configuration classes. There you can instantiate yourself your beans in the configuration classes where you will wire all dependencies togethers. As such there will be absolutely 0 annotations in the classes that implements your business logic.

Also the old XML configuration can be seen as a way to keep them separate.

Finally, there is some times where you may need the ApplicationContext of Spring, you can just hide him behind a simple abstraction that answer just what you need. I don't bother to do it myself though, but it doesn't happens in my classes handling the businness logic. If you need events, create event handle that just catch the event and call the right services handling the business logic for it. As such you will not have your business logic directly wired to the event bus of your framework.

EDIT : Following what David Arno said, I'll add this to my answer.

If you understood it well, you will understand that in fact I'm not telling you really to abstract the framework but instead to have classes independant of your framework (where your business logic is implementend) and to have classes making the connection between the framework and your independant classes. As such I join David Arno on the claim that you don't abstract frameworks.

0

You can:

  • Separate domain logic from the framework. Use the ports and adapters architecture (aka hexagonal) where only the external part knows about spring. This can be enforced by using a several maven modules where only de outer module knows about the framework.

  • Inject dependencies by constructor (bonus if you make dependencies immutable).

  • Avoid the magical tags: @autowired, @value, etc. Configure dependencies y the configuration file. This will decouple your properties from the places where they are found. Instead of having a Service with @value("timeout.in.millis") you have a long timeoutInMillis that in the configuration file is get from this place. Avoid autoscan of dependencies.

  • You can still use the same classes ...but as a POJO. Spring Data for example has excelent classes.

As a nice side effect you will have a more testeable code

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.