Open yzxbmlf opened 2 years ago
Quick hack to demonstrate the concept. The value here is that the core NetOrganizerApp doesn't know or care how data is fed into it (input ports) and it doesn't care what happens downstream (output ports. This makes the architecture highly testable (by providing alternative adapters) and flexible (new adapters can be added/plugged-in).
from typing import NamedTuple
from abc import ABC, abstractclassmethod, abstractmethod
from typing import List
class KnownDevice(NamedTuple):
name: str
mac: str
group: str
def __str__(self):
return f'{self.name} with MAC {self.mac} in {self.group}'
class KnownDevicesPort(ABC):
@abstractmethod
def load() -> List[KnownDevice]:
pass
@abstractmethod
def save(list_of_known_devices: List[KnownDevice]) -> None:
pass
class KnownDevicesYamlFileAdapter(KnownDevicesPort):
def load(self) -> List[KnownDevice]:
print("Loading from file")
jasons_ipad = KnownDevice(name="Jason's iPad", mac="10:ab:cc", group="jasons_devices")
list_of_known_devices: List[KnownDevice] = []
list_of_known_devices.append(jasons_ipad)
return list_of_known_devices
def save(self,list_of_known_devices: List[KnownDevice]) -> None:
print("Saving to file ")
for known_device in list_of_known_devices:
print (known_device)
class NetOrganizerApp():
def __init__(self, known_devices_port: KnownDevicesPort) -> None:
self.known_devices_port = known_devices_port
def do_something(self) -> None:
list_of_known_devices = self.known_devices_port.load()
self.known_devices_port.save(list_of_known_devices)
known_devices_port = KnownDevicesYamlFileAdapter()
net_organizer_app = NetOrganizerApp(known_devices_port=known_devices_port)
net_organizer_app.do_something()
The idea of ports and adapters I feel provides an opportunity to clean up the structure and make it easier to expand support beyond Meraki and also enable different user interfaces beyond the command line. Also, as I think about classification I want to enable classifiers to be easily plugged in. The first classifier I have in mind is a simple manual classifier.
The other key benefit I think is testability. The problem with lots and lots of unit tests is it makes the actual code harder and longer to refactor. They are still valuable and have their place, but I want to be able to easily re-factor the core of Net Organizer without a) breaking things but also b) not having to refactor a ton of tests too. I think this video provides a good foundation https://www.youtube.com/watch?v=EZ05e7EMOLM
https://alistair.cockburn.us/hexagonal-architecture/