Sì, ci sono degli svantaggi
Il codice che è facile da leggere è buono, ma fa anche attenzione a ciò che il codice comunica . Quando i metodi di un oggetto restituiscono sempre l'oggetto, comunica un paio di cose:
- Ho bisogno di una configurazione avanzata che non sia necessariamente ovvia in quale ordine le cose dovrebbero essere impostate o configurate
- Ogni successiva chiamata al metodo costruisce sull'ultimo
Caso di utilizzo valido: query del database ad hoc
Le librerie di classi esistono nella maggior parte delle lingue che consentono di eseguire query su un database senza ricorrere a codice SQL codificato. Prendi l'Entity Framework per .NET come esempio:
DBContext db = new DBContext();
List<Post> posts = db.Posts
.Where(post => post.Title.Contains("Test"))
.OrderBy(post => post.DateCreated)
.ToList();
Questa è un'interfaccia fluente dove ogni successiva chiamata al metodo si basa sulla precedente. La lettura di queste chiamate ha senso logico nel contesto dell'interrogazione di un database.
Caso di utilizzo non valido: zucchero sintattico per l'impostazione delle proprietà
Ora utilizziamo lo stesso modello con la classe Post
:
public class Post
{
public string Title { get; set; }
public DateTime DateCreated { get; set; }
public string Body { get; set; }
public Post SetTitle(string title)
{
Title = title;
return this;
}
public Post SetDateCreated(DateTime created)
{
DateCreated = created;
return this;
}
public Post SetBody(string body)
{
Body = body;
return this;
}
}
Ora vediamo come useresti questa classe:
Post post = new Post()
.SetTitle("Test")
.SetDateCreated(DateTime.Now)
.SetBody("Just a test");
Quando vedo questo codice, faccio subito questa domanda: "Dopo aver chiamato SetBody
, interroga il database? Devo chiamare un altro metodo per dire" Ho finito? ""
Che cosa il metodo concatenato chiama comunica con il codice utilizzando la classe Post
?
- Ho una configurazione complicata
- Ogni chiamata di metodo crea sul precedente
Questo in realtà è vero? No. La classe Post
non ha una configurazione complicata. Impostando il titolo, la data creata e il corpo non si costruiscono l'un l'altro verso un obiettivo finale più complicato. Hai schiacciato un piolo quadrato in un buco rotondo.
Lo svantaggio del concatenamento del metodo autoreferenziale è che comunichi che sono necessarie più chiamate al metodo per fare qualcosa e che ogni chiamata si basa sull'ultima. Se ciò non è vero, il concatenamento dei metodi potrebbe comunicare la cosa sbagliata agli altri programmatori.
Quando i tuoi colleghi hanno detto:
Fluent interfaces should not be implemented just for convenience, but for semantics
Erano assolutamente corretti. Un'interfaccia fluente, o metodo di concatenamento, comunica qualcosa di per sé che potrebbe non essere vero.