The interfaces are an important tool in the Object Oriented wolrd, but there are many developers who don't like to use it, and don't see the advantages they offer.
In order to explain the importance of the interfaces, we will follow the integration process between a big smartphone company called Fuwei and its technology provider, Famsung.
Fuawei - The smartphone company
Fuawei is one of the biggest technology companies in the world, it produces smartphones and sells them around the globe.
A few years ago, the direction board decided to externalize the chips production to Famsung, in order to allow the company to increase the production of smartphone.
Famsung has a cool REST API which allows clients to order new components and retrieve the provider specification. Fuawei decided to use this Web Service to ask for the chips needed.
Fuawei had a small technology team, which was in charte to create the technological requirements of the products, it was the CORE TEAM. As well to ensure the integration with Famsung was successfully, Fuawei created another team called the Integration TEAM.
Unluckily, The Integration Team didn't know much about interfaces so the first integration attempt get the following result.
import requests
from fuawei.fuawei_chip import FuaweiChip
class Fuawei:
def create_phone(self):
famsung_chip_data = requests.get('http://famsung/web-service').json()
famsung_specification_parsed = self.parse_famsung_specification(famsung_chip_data)
return self.create_fuawei_chip(famsung_specification_parsed)
def parse_fansung_specification(self, data):
# Many lines to parse from fansum format to any more friendly format
return {}
def create_fuawei_chip(self, data) -> FuaweiChip:
# Many lines to build from our friendly format to FuaweiChip
return FuaweiChip()
This code is shared between the Core Team, and the Integration Team.
The core team and the integration team fought many times, because of the many conflicts they suffered between each other, also those issues caused many bugs.
Now, in the present, Famsung and Fuawei relation is uncertain, the politics from their respective countries are not in good terms, and they have forbidden to work together. Finally, the Fuawei CEO has decided to assume the chip production in their own factories.
In order to replace Famsung provider, Fuawei is creating a Components Team. They have decided to use gRPC technology as the communication method because it is more efficient.
But the integration team is already using the Famsung REST API, in many parts of the product, refactor the whole product might cost them too much time.
What could the integration technology team do?
The Core and Integration teams have decided get a time off in order to get the best solution to this problem. It is going to be hard this time, but they don't want to do twice the same mistake.
Dangers
- The logic is not isolated
- Too coupled to third party libraries
- The teams are not able to work confident
- So easy to create bugs
For example: Imagine the requests or grpcio library get deprecated, in the first iteration you would have to migrate big part of the project too, in order to replace them to other libraries.
One of the core developers has recently read the Clean Architecture Book, and he would like to apply it to this situation in order to decouple the integration logic from the core logic.
The importance of the Intefaces
This time, they will create a couple of classes with the specific logic for each integration, they would like to keep the old Famsung Integration in case the necessities change in the future.
The integration team likes the solution proposed by the Core Team. But they they would like to add a few changes in order to work better.
The teams are going to divide the code, isolating the different parts for each team, this way they will avoid conflicts among different teams.
In order to coordinate both teams, they have decided to create an interface called TechProvider
with an order_chip
method, and it would be in charge of the Core Team, to prevent error in the core logic.
The Core Team will be in charge of the core logic and the provider contract, and the Integration Team will handle the integration logic with the different technology providers, always implementing the TechProvider
interface.
These changes will add many advantages to the company.
Advantages
- The teams will be able work without conflicts
- They can create new integration with new provider without too much effort
- They don't rely on specific technology (which can change and be deprecated)
- The specific business logic is isolated avoiding generating undesired dependencies.
After a few months, they accomplished the task with the following result.
Code
Core Team Area
from fuawei.phone import Phone
from fuawei.tech_provider import TechProvider
class Fuawei:
def __init__(self, provider: TechProvider):
self.provider = provider
def create_phone(self) -> Phone:
chip = self.provider.ask_chip()
return Phone(chip=chip)
import abc
from fuawei.fuawei_chip import FuaweiChip
class TechProvider(abc.ABC):
@abc.abstractmethod
def ask_chip(self) -> FuaweiChip:
pass
Integration Team
import requests
from fuawei.fuawei_chip import FuaweiChip
from fuawei.tech_provider import TechProvider
class FamsungTechProvider(TechProvider):
def ask_chip(self) -> FuaweiChip:
return self._build_fuawei_chip(requests.get('http://fuawei-chips/web-service').json())
def _build_fuawei_chip(self, data) -> FuaweiChip:
# On these lines you would have a lot of parse work in order to extract all the necessary information to
# build your fuawei chip
return FuaweiChip()
import grpc
from fuawei.fuawei_chip import FuaweiChip
from fuawei.tech_provider import TechProvider
class FuaweiTechProvider(TechProvider):
def ask_chip(self) -> FuaweiChip:
fuawei_service = grpc.insecure_channel('fuawei/web-service')
# Communication to the gRPC service of the Fuawei Provider
return FuaweiChip()
Because of they know this code may help other developers, they decided to push the whole repository to github.
Conclusion
Structuring your code is key piece of software development, and the interfaces are an important tool to accomplish it.
The interfaces will keep your architecture organized and decoupled, they empower you to manage the dependencies you use in your project, and help you to test each part of your software project in a isolated way.
Also, a good architecture will help you to keep the technical debt low, it will avoid conflicts with other team members and even other teams, and it will allow you to work more confident in the features you are developing without being worried about creating bugs.
I have used another OOP principles in the example, I would recommend check the SOLID principles out if you don't know any of them.
Resources
https://github.com/juanbenitopr/fuawei
https://www.amazon.es/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164/
Top comments (0)