Friday 12 April 2019

Your library is a monolith and I don't want to use it

Warning! This is a bit of a rant.

Dogma

As developers we are taught to reuse code. After all, it saves time to reuse code, rather than rewriting it. This obviously means that we should write libraries which we can reuse.

Your library functionality is placed in neat folders to signify the functionality that is implemented, and you probably have StringHelpers, Authentication, HtmlHelpers, EventHooks, Serialization etc. You even decide to unit test all of these methods.

Great! Now you have a great suite of functionality which you can use on any project! You are now officially a good developer!

The Problems

Over time, these libraries get larger and larger. More and more functionality is added to those neat folders until you have a monolith library. It's huge!

Internal Dependencies

If you have done your job correctly as a developer who reuses code, your library probably has dependencies on other parts of the library. So many internal dependencies that when you decide to update / fix some functionality you risk breaking existing functionality. If this happens then you truly have a monolith.

Third Party Dependencies

The worst part of it is when your library has dependencies.  Here's an example of why this sucks...

Imagine if I just want to use ONE deserialisation method in the library. Well that library has authentication which has a dependency on Microsoft.Identity.Client, which has dependencies. OMG! All I wanted to use was a single deserialisation method! My project now has a jillion dependencies which are absolutely not used!

I know what you're about to say... tree shaking. But frankly I think that's a hack.

Where is the... ?

To make matters worse, new developers come to the mix and cant find the thing their looking for. So they add their own bit of functionality which is almost exactly the same as yours... further bloating your once beautiful library.

It's too big to use

The most tragic thing about your monolith library is that it has become so large and fragile that no one wants to use it :(


A Different Approach

SOLID

Consider SOLID principals which creating your libraries. Don't just write one or two libraries. Write many! Remember all those folders you had to signify different types of functionality? Well ALL of those should be different libraries. You could even consider taking the files inside those folders and making those individual libraries too!

Interface all things

Remember all those internal dependencies you have? Consider interfacing the internal dependencies, and then releasing the interfaces as separate packages. 

This may seem like a daunting task, but it gives you far greater flexibility, and makes your code more maintainable.

Here's an example...

Imagine you have an emailing library which has dependencies on your Azure Blob Storage library and your SendGrid library. This library is tightly coupled with the other two. If you ever want to swap the SendGrid library for MailGun, then you will have bloated unused dependencies. 

This is where interfacing comes to the rescue. If you had your dependency on an IRestEmail interface, then you could swap your implementation as you wish, with no other dependencies.

I'll discuss this further in a future post.


Conclusion

I hope that I have convinced you that your monolith libraries need splitting out. Don't just think that reusing code means creating a single library. You can have dozens of libraries. If they have dependencies on eachother then that's fine, because you have have different versions of each library. Definitely consider interfacing those libraries as much as possible so you can swap out implementations.

Comment below if you found this helpful.







No comments:

Post a Comment