The API we presented last time had a problem - it required users to remember to call Initialize() before an instance could be used without problems occurring.

Sometimes this is called temporal coupling, because the ordering, or timing, of calls need to be just right.

In C#, our object may have a declaration like this:

public class ImportOperation
{
    public ImportOperation() { 
        // ... elided ...
    }

    public void Initialize(ServiceClient client) 
    {
        // ... elided ...
    }
}

and consumption like this:

var operation = new ImportOperation();
operation.Initialize(client);

or in Go, the declaration:

type ImportOperation struct {
    // ... elided ...
}

func (op *ImportOperation) Initialize(client ServiceClient) {
    // ... elided ...
}

and consumption:

var operation ImportOperation
operation.Initialize(client)

The first, and perhaps most obvious, way to improve things would be to use a constructor, so that an uninitialized instance can’t be obtained in the first place.

In C#, you’d end up with this declaration:

public class ImportOperation
{
    public ImportOperation(ServiceClient client) { 
        // ... elided ...
    }
}

and this consumption:

var operation = new ImportOperation(client);

This isn’t a bad approach, but it doesn’t always work.

For one, C# does not have asynchronous constructors, making it impossible to roll Initialize() into the constructor if it needs await when invoked.

Also, Go doesn’t have constructors - and the idiomatic use of uninitialized structs (with useful zero values) would seem to pose a blocker too.

How else can we make the API one with a pit of success where users can’t get things wrong?

Comments

blog comments powered by Disqus
Next Post
Factory methods and functions  05 Mar 2023
Prior Post
An Inconvenient API  18 Feb 2023
Related Posts
Browsers and WSL  31 Mar 2024
Factory methods and functions  05 Mar 2023
An Inconvenient API  18 Feb 2023
Method Archetypes  11 Sep 2022
A bash puzzle, solved  02 Jul 2022
A bash puzzle  25 Jun 2022
Improve your troubleshooting by aggregating errors  11 Jun 2022
Improve your troubleshooting by wrapping errors  28 May 2022
Keep your promises  14 May 2022
When are you done?  18 Apr 2022
Archives
February 2023
2023