Friday, March 20, 2015

Avoid primitive-obsession-related problems by adding behavior to Angular resources using Underscore extend function

One of the problems I found while working on a legacy Angular application last year, was resources with deeply nested structures that were being accessed directly from many different places.

That code was revealing too much about the resources inner structure and that meant that the code that interacted with the resources was spread all over therefore generating a lot of duplication. That made it really hard to change and understand.

It was suffering from a severe case of primitive obsession in the form of directly using raw resources.

To prevent that from happening in the Angular application we are developing now, we have added behavior to Angular resources using Underscore extend function. By doing it, we have managed to hide the inner structure of the resources from its users and also created an object that has attracted the resource-handling code that was before spread all over.

These strategy has put us in a much better position. Now if the structure of the JSON data of a resource changes for any reason, we have only one place to go to adapt to that change.

It also has improved the overall readability of the code by making it possible to give proper names to the different resource-handling functions.

Here it's an example from our code:

Notice the use of the extend function to add the behavior in TrackMethods to the prototype of Track resource.

TrackMethods is an object containing several functions that hide the inner structure of the Track resource and make its use more readable: The only restriction we put ourselves is that behavior extensions like TrackMethods can't have any state.

Currently TrackMethods contains only accessors, but it will surely grow as the application evolves. All the functions in TrackMethods were discovered in other parts of the code and moved into it. We try to stay alert at new opportunities to attract more code into these behavior extensions.

Another advantage we've found is that these behavior extensions can be easily tested using fake resources.

These are TrackMethods current tests:

This strategy of extending Angular resources with behavior is an alternative to encapsulate collection which is working quite well for us to avoid primitive-obsession-related problems.

No comments:

Post a Comment