bluerobotics / BlueOS

The open source platform for ROV, USV, robotic system operation, development, and expansion.
https://blueos.cloud/docs/
Other
166 stars 81 forks source link

Improvement on endpoints API #183

Open rafaellehmkuhl opened 3 years ago

rafaellehmkuhl commented 3 years ago

The context:

We had a class called Endpoint, that receives 3 arguments: connection_type, place and argument. Right now, with the new metadata, this class receives 4 more arguments: name, owner, persistent and protected, with the last two having default false values.

The problem:

Two many arguments to instantiate an endpoint, with some of those arguments being unrelated (some are metadata and some are connection data).

The solution:

Separate the Endpoint class into 3 classes:

The base ConnectionEndpoint class would be abstract, and represents what an Endpoint should do, but not how.

MavlinkEndpoint would inherits from ConnectionEndpoint and implement it (would have basically all the code that is in Endpoint today).

CompanionEndpoint would be a class that has the companion metadata we want to add (name, owner, persistent and protected) and receives also an ConnectionEndpoint instance.

In that way, we better separate the concerns (ConnectionEndpoint instance will store connection information while CompanionEndpoint instance stores the metadata), we make the calls smaller and more clear and we open the possibility for future implementations of new protocols.

patrickelectric commented 3 years ago

I would recommend to make MavlinkEndpoint a builder, where you can configure it directly with:

MavlinkEndpoint.create()
    .with_endpoint(EndpointData(Endpoint.TCPout, "0.0.0.0", 5600))
    .with_configuration(EndpointMetadata(name, owner, persistent, protected))
# and
MavlinkEndpoint.create()
    .with_endpoint(EndpointData(Endpoint.TCPout, "0.0.0.0", 5600))
    .new_configuration()
        .set_name(name)
        .set_protected()

As you can see this makes it simpler and much readable.

rafaellehmkuhl commented 3 years ago

CompanionEndpoint(
    EndpointMetadata(name, owner, persistent, protected),
    MavlinkEndpoint(connection_type, place, argument)
)
patrickelectric commented 3 years ago
rafaellehmkuhl commented 3 years ago
  • The problem with that approach is that if metadata needs extra fields it'll start the problem all over again.
  • Not all fields are necessary, you can have protected and persistent off my default and only true require name and owner.
patrickelectric commented 3 years ago

If metadata happens to need extra required arguments, there's really nothing we can do besides adding them, right?

Yes, you can use a builder validation.

MavlinkEndpoint.builder()
    .with_endpoint(EndpointData(Endpoint.TCPout, "0.0.0.0", 5600))
    .new_configuration()
        .set_name(name)
        .set_protected()
        # missing required
    .create() # create will check the validation and trow or return an optional/result
rafaellehmkuhl commented 3 years ago

What would be the advantage of doing that instead of the below?

CompanionEndpoint(
    EndpointMetadata(
        name=name, 
        owner=owner, 
        new_required=new_required,
        persistent=persistent,
        protected=protected,
        new_optional=new_optional
    ),
    MavlinkEndpoint(
        connection_type=connection_type,
        place=place,
        argument=argument
    )
)