Domanda di progettazione API per una classe Builder

0

Ho un paio di domande sul modo migliore di presentare l'API di un costruttore.

Diciamo che abbiamo un enume che vorremmo che un utente impostasse il costruttore:

public enum PositionType
{
    Anywhere,
    First
}

Ecco un esempio di una classe Builder, con i due diversi modi di fornire un'API di impostazione (commentata):

public class Builder
{
    private PositionType? _position { get; set; }

    public Builder()
    {
        _position = null;
    }

    // Option 1: a single method for the user to set a type explicitly:
    public Builder SetPosition(PositionType type)
    {
        _position = type;
        return this;
    }

    // Or, Option 2, provide separate methods for each value:
    public Builder CanPositionAnywhere()
    {
        _position = PositionType.Anywhere;
        return this;
    }

    public Builder MustBePositionedFirst()
    {
        _position = PositionType.First;
        return this;
    }
}

Un vantaggio del secondo approccio è che posso rendere interno l'enum PositionType e che l'utente non deve conoscere o preoccuparsi dei valori.

Ma sicuramente, se un enum ha molti valori, deve essere complicato per un utente leggere ogni metodo e sapere quale scegliere? Non sono sicuro su questo.

Infine, dato che il Builder avrà un singolo valore impostato per PositionType, ha senso controllare e lanciare un'eccezione se è già stata impostata?

Quindi gli esempi precedenti cambieranno in qualcosa del genere:

    // Option 1: a single method for the user to set a type explicitly:
    public Builder SetPosition(PositionType type)
    {
        if (_position != null) throw new Exception("Already been set.");

        _position = type;
        return this;
    }

    // Or, Option 2, provide separate methods for each value:
    public Builder CanPositionAnywhere()
    {
        if (_position != null) throw new Exception("Already been set.");

        _position = PositionType.Anywhere;
        return this;
    }

    public Builder MustBePositionedFirst()
    {
        if (_position != null) throw new Exception("Already been set.");

        _position = PositionType.First;
        return this;
    }

Alla fine, sento che non dovrebbe importare troppo, ma mi sto appoggiando più verso il controllo e il lancio. Forza l'utente ad essere più attento a ciò che sta facendo.

Voglio solo avere un'idea su come progettare questo scenario e perché.

Grazie!

    
posta Isaiah Lee 11.07.2018 - 15:56
fonte

0 risposte

Leggi altre domande sui tag