Tak, są wady
Kod, który jest łatwy do odczytania, jest dobry, ale należy także uważać na to, co kod komunikuje . Kiedy metody obiektu zawsze zwracają obiekt, komunikuje się kilka rzeczy:
- Potrzebuję zaawansowanej konfiguracji, która niekoniecznie jest oczywista, w jakiej kolejności należy ustawić lub skonfigurować rzeczy
- Każde kolejne wywołanie metody opiera się na ostatnim
Prawidłowy przypadek użycia: zapytania do bazy danych ad hoc
Biblioteki klas istnieją w większości języków, które pozwalają wyszukiwać w bazie danych bez uciekania się do SQL. Weźmy przykład Entity Framework dla platformy .NET:
DBContext db = new DBContext();
List<Post> posts = db.Posts
.Where(post => post.Title.Contains("Test"))
.OrderBy(post => post.DateCreated)
.ToList();
Jest to płynny interfejs, w którym każde kolejne wywołanie metody opiera się na poprzednim. Logiczne czytanie tych wywołań ma sens w kontekście odpytywania bazy danych.
Nieprawidłowy przypadek użycia: cukier składniowy do ustawiania właściwości
Teraz zastosujmy ten sam wzór z Post
klasą:
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;
}
}
Spójrzmy teraz, jak używałbyś tej klasy:
Post post = new Post()
.SetTitle("Test")
.SetDateCreated(DateTime.Now)
.SetBody("Just a test");
Kiedy widzę ten kod, natychmiast zadaję to pytanie: „Czy po wywołaniu SetBody
wysyła zapytanie do bazy danych? Czy muszę wywoływać inną metodę, aby powiedzieć„ gotowe ”?
Co łańcuchowe wywołania metod komunikują się z kodem za pomocą Post
klasy?
- Mam skomplikowaną konfigurację
- Każde wywołanie metody opiera się na poprzednim
Czy to rzeczywiście prawda? Nie. Post
Klasa nie ma skomplikowanej konfiguracji. Ustawienie tytułu, daty utworzenia i treści nie opiera się na sobie w celu osiągnięcia bardziej skomplikowanego celu końcowego. Wcieliłeś kwadratowy kołek w okrągły otwór.
Wadą samodzielnego łączenia metod jest to, że komunikujesz, że do wykonania czegoś potrzeba wielu wywołań metod i że każde wywołanie opiera się na ostatnim. Jeśli nie jest to prawdą, wówczas łączenie metod może przekazywać niewłaściwe informacje innym programistom.
Kiedy twoi współpracownicy powiedzieli:
Płynne interfejsy nie powinny być implementowane tylko dla wygody, ale dla semantyki
Miały absolutną rację. Płynny interfejs lub łączenie metod komunikuje coś samo w sobie, co może nie być prawdą.