How to calculate the stability of a component

Image for post
Image for post
Photo by Juan Gomez on Unsplash

Calculating the stability of your component is a good practice for building a solid architecture. It is a fantastic method to detect areas that are sensitive to failure in future changes. In this post I’ll show you how to do it with a simple formula.

Hi again, I’m very enthusiastic for that post because I resolve the question, it’s possible to calculate the unstable component?

Yes! I have the magic formula for resolve that.

Sorry I’m sounds like a commercial people. That formula appears in one of my favourite book Clean Architecture by Robert C. Martin.

Image for post
Image for post

Looks simple, no? Ok I explained what the meaning all parts:

  • Stability: Is a value between 0 and 1 where 0 is the maximum stability of the component and 1 is the maximum instability.
  • Output range: This parameter indicates the number of classes of the component that depend on classes external to the component.
    The number of classes imports.
  • Input range: This parameter indicates the number of external classes of the component that are dependent on classes of the component.
    The number of components that import my component.

For example this is a example for maximum stability:

Image for post
Image for post

In this case our component is stable because three external components depend on it and any changes to our component need to be applied to the other components.

Example for instable component:

Image for post
Image for post

In this case our component is unstable because no component depends on it and it has three external dependencies. On this case any change in component 1, component 2 or component 3, force to update our component. As a result, this component is easily subject to future changes imposed by the other components.

In a nutshell, the formula can show us how easy or difficult it is to change your code.

In a real environment. It is not a good idea use only stable components because nothing would change, it would be impossible to make modifications. The best option is to have a good balance between stable and instable components, look at this example of code with Django framework.

def get_order_summary(order_id):
try:
order = Order.object.get(id=order_id)
except ObjectDoesNotExist:
return HttpResponse(’Order not exist’, status=404)

This example is very common to exist in a helper.py or utils.py file, no?

Image for post
Image for post

Ok, according to the formula, this function is used by external files and has no import. So, it’s stable, Great!!! This function is used in the user’s shopping cart, in the order view, in the buyer’s order manager and in different workflows.

Ergo, this code is very difficult to change because, 1 change in this function may require updating all components that use it.

Well, over time, we realize that the database is saturated with many queries. And we detect that our function makes a query that we could avoid, if we change order_id to order object.

def get_order_summary(order):
return {
'total': order.total_amount,
'sub_total': order.sub_total_amount,
'items_total': len(order.items),
...
}

Great job!! And now our stable function change to CHAOS function. Because that change produced errors in our unittest and in our integration test.

What?!!

Our functions were very stable when we created them. But we detect some errors and that produces many changes in other parts of our project.

Be careful with functions like this. The best recommendation is to keep it simple. Detect what unnecessary steps you perform, such as obtaining a database object or opening files, sending external requests (API), reading cache, business logic or something else … be careful. Try to make a simple component, to avoid future changes.

So understanding all this, the unstable component in our case the controller that is going to render the shopping cart view would be something like this.

def shopping_cart_view(request):
user = get_user_authenticated(request)
order = get_shopping_cart(user, request)
data = get_order_summary(order)
return render(request, 'shopping/cart.html', data)

This instable function use many stable functions for example get_user_authenticated i think in all of pages when required a authenticated user execute this function because is necessary run the same checks in all of pages.
Other stable function is get_shopping_cart on this part is posible to check and validate user session with shopping cart.
And finally get_order_summary on this point is unnecessary call database again because previous function check, validate and create correctly order object.

Do not take this example literally as I only use it to demonstrate the practice of interspersing stable and unstable methods in a simple way. The method shown in this post will help you to be able to perform an analysis or create a metric where you can evaluate or measure the severity of a specific change.

Conclusion

When we create a stable component, function, class… we have to spend extra time to detect unnecessary actions. Because if your component is used in many points of your project, when you try to update it and our project is finished or during the development process it is possible to provoke CHAOS.

I hope you like the post, thanks for reading it.

Written by

Senior Software engineer at @eventbrite

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store