Life Is Wrapped in Mystery

Why does life live in this world? Why does life come to this world? Why does life go from this world? Life is wrapped in mystery. If the mystery is solved, spirits will reveal themselves.

Smartphone

独家优惠奖金 100% 高达 1 BTC + 180 免费旋转




SOLID and IoC in python

It was a long journey for me before I found the way to truly feel “at home” coding in python. I’m here to tell you what I discovered along the way.

Whenever I write an application/system/program/etc. I always keep in mind some core questions.
- Will this grow in the future?
- Who will use it?
- Will others need to read/develop this code?
- Is the code testable?

The answers to all of these always bring me back to the following life savers:

I like to write small, simple services and handle the dependencies using dependency injection

Let’s write a simple app.
What should our app do? Read something, process and send? Sounds good, let’s go.

Our app will help us search for a new apartment, hopefully doing most of the hard work for us ;)
Read apartments from different sources, filter-in the apartments the answers our requirements (budget for now) calculate the apartments score and then notify us.

We’ll start by reading apartments from a CSV file, filter them by price and then publish them by printing in the console (boring!)

First let’s define the apartment object

Before writing the actual implementation, I usually like to start with the “interfaces” of the requirements. (I know it’s not conventional, but bear with me)

ApartmentsReader will be responsible for fetching the apartments from different sources.

NOTE: notice the “raise NotImplementedError()”, if you’re using PyCharm, it’s syntax sugar for “interfaces”

Next, our filter!

Our publisher:

And now for the main skeleton:

Now let’s discuss the power of what we’ve got so far.

For our requirements, we could have just written the whole thing under the “run” function (read the file, calculate the score and print to the screen). But this way we’re not coupled to those basic requirements. We can easily add more readers, remove publishers, change the way we want to filter… and all without changing the searcher class one bit!

Following SOLID’s Single Responsibility, each class is doing one specific task and nothing else (this also make it easier to test).
Also if we want to change the implementations, we don’t need to rewrite the app, we just need to initialize it differently in the main. (woohoo for SOLID’s Open/Close principle!)

There is nothing special here, just implementing our interfaces (you may skip to the next part)

Quickly let’s create implementations:

File reader:

Console publisher:

Price filter:

Now for the main.py:

This where we decide how the searcher would work, if we want to change publishers or readers or even the filter, we do it here. This is our application setting concentrated conveniently into one place.

Ok, so now we got our initial requirements set… but this app does almost nothing, it’s not the real world, it’s hard to get our apartments data into files in our convenient format, the price is hard coded, and we won’t look at the console all day.

Let’s add more implementations, that may remind us the real world better.
We’ll read the data from API, and notify by Email.

So let’s create a fake api:

This API will always return same fake data, and as most apis, they don’t always bring us exactly what we want, so we’ll need to map those results to make it useful.

Now for the api reader:

And finally let’s send us mail when we found new apartment:

Fake email client:

Now let’s use it:

Oh wow, those dependencies are getting out of hand, also we may need configurations now…

Cynergy — Simple python library that provide container for your dependencies and manage your app configurations.

So let’s create simple application initializer to concentrate all of our settings:

Now our main will look like:

NOTE:

We’ll do the same for the rest of classes (we can of course register them manually, but that’s no fun) assuming we can’t change our API reader and the EmailClient as for this example they are “3rd parties”.

Now, let’s say we want to scale and put our configuration in Database.
It’ll be easier than you think, we just need to implement our ConfigProvider for Cynergy that’ll do that for us!

This is very powerful thing, we just moved all of our config to database without changing a single line in our application’s core!

Ok now that we’re done, let’s talk about what we’ve got so far.

Our apartments app can be in real use now, we can add more readers and publish through many channels, we can change the way we want to filter and (I’m trying to objective here) I think it is very easy to get into this code after short look; you don’t have to understand every part of the code. You can just take a look in the ApatmentsSearcher, go to the app initializer and get going!

In my opinion following those guidelines while developing an app is very useful, especially if you’re part of a team.
Make your code readable, make your code testable, control your app’s flow, thing about the next person who’s will try to add features, think about future requirements and make it easier for you to extend your app.

I’d be happy to hear your opinion, questions and thoughts!
Hope you enjoyed and good luck :)

May the code be with you.

Add a comment

Related posts:

Here Is The Key To Get Sh!t Done

Getting sh!t done is not impossible.

The Case for Investing in Employee Ownership

Typical progressive approaches to addressing the growing income and wealth gap — minimum wage, unions, taxation, or guaranteed income — have failed to move the needle, argue Marjorie Kelly and Karen…

Set up a comfortable Home office to reduce physical and mental impact

In this article I will tell you what physical and mental impact I’ve noticed my self over the last years and what I’ve done against it. I will get you tips and ideas of how to create a better…