jeudi 2 novembre 2023

Avoid temporal coupling in class that requires establishing a connection

I am designing a class that provides a means for interacting with a Bluetooth Device. My design roughly looks like this:

class Device
{
    private bool _isConnected;
    private readonly ulong _bluetoothAddress;

    public event EventHandler<Message> MessageReceived;

    public Device(ulong bluetoothAddress)
    {
        _bluetoothAddress = bluetoothAddress;
    }

    public async Task ConnectAsync()
    {
        // Async connection logic...

        _isConnected = true;
    }

    public async Task SendMessageAsync(Message message)
    {
        if (!_isConnected)
        {
            throw new InvalidOperationException("Not connected");
        }

        // Send logic...
    }
}

In order to send a message to the device, the client must call ConnectAsync to put the device in a connected state. Then, messages can be sent via SendMessage and received via the event Message received.

What I don't like about this design, is that it introduces temporal coupling into the API. The client is always required to call ConnectAsync before SendMessage. Lazily calling ConnectAsync from SendMessage when the device is disconnected is also not an option, since the connection must be established to receive events.

Aucun commentaire:

Enregistrer un commentaire