While I know this is the tight coupling example:
class User:
def __init__(self):
pass
def get_status(self):
api_client = APIClient()
status = api_client.get_user_status()
return status
And this is the loose coupling example:
class User:
def __init__(self, api_client):
self.api_client = api_client
def get_status(self):
status = self.api_client.get_user_status()
return status
Then what about these:
Example 1
class User:
def __init__(self):
self.api_client = APIClient()
def get_status(self):
status = self.api_client.get_user_status()
return status
Example 2
class User:
def __init__(self):
self.api_client_class = APIClient
def get_status(self):
api_client = self.api_client_class()
status = api_client.get_user_status()
return status
Example 3
class User:
def __init__(self):
pass
def get_api_client(self):
return APIClient()
def get_status(self):
api_client = self.get_api_client()
status = api_client.get_user_status()
return status
All those 3 examples makes it easy to stub the APIClient
dependency in unit tests and it also allows the User's class consumer to inject something other than APIClient
(example 3 is the worst one anyway I guess).
But the question is: Are those examples tightly coupled or not? Which of these examples is the best one? Are they proper or not? Are they better than the tightly coupled example?