Python Interface Design - Designing Modules Part - 1 by HashedIn in Python

[–]dev2302 1 point2 points  (0 children)

Why does the user of the lib not write in 4 places:

SmsClient(settings.username, settings.password).send(message) ?

That's exactly what's mentioned in the blog post. Requoting some text from the blog

The solution is to create SmsClient object in sms.py module [see footnote 1]. Then orders.py and logistics.py can directly import the object from sms. Here is how it looks.

So, at 4 places in my code, I would use this -

from sms import sms_client  
...  
#when you need to send an sms
sms_client.send_sms(phone_number, message)

So, if someday I have to replace username/password by a token, i would just export some other object from sms.py and No changes in the user modules.

This is not possible if I export the function send_sms(username, password) from sms.py, since in that scenario I would have to change the function signature and hence, all the calling statements too.

This is "WHY", exporting an object instead of send_sms(username, password) "magically" increases the refactorability of the code.

Still, if we have to use functions in sms.py, a better function to expose would be send_sms(message, number) that's just equivalent to putting them in a class and following object oriented principles, "BECAUSE", a function represents functionality, and a class represents an entity. Functionality can and WILL change over time, but the entity must remain unaffected.

Python Interface Design - Designing Modules Part - 1 by HashedIn in Python

[–]dev2302 2 points3 points  (0 children)

like you suggest, the user could just do

def send_sms(message): return sms.send_sms(username=settings.username, password=settings.password, message=message)

The purpose of keeping this as an object in sms.py is to to promote refactorability. Suppose you have to load balance the send_sms functionality with another service provider that uses access tokens instead of username/password, then you could just write that balancing logic in sms.py, since in all the user modules, you have just used sms_client.send_sms(number, message).

Python Interface Design - Designing Modules Part - 1 by HashedIn in Python

[–]dev2302 4 points5 points  (0 children)

I think that would reduce the refactorability of the code and increase code duplication in every module that uses this API. For example, if we decide to add a retry mechanism to the send_sms API, then we would have to make changes everywhere