Jakie są zalety i wady posiadania statycznych metod tworzenia obiektów nad konstruktorami?
class Foo {
private Foo(object arg) { }
public static Foo Create(object arg) {
if (!ValidateParam(arg)) { return null; }
return new Foo(arg);
}
}
Niewiele mogę wymyślić:
Plusy:
- Zwraca null zamiast zgłaszania wyjątku (nazwij go
TryCreate). Może to sprawić, że kod będzie bardziej zwięzły i czysty po stronie klienta. Klienci rzadko oczekują awarii konstruktora. - Twórz różne rodzaje obiektów z wyraźną semantyką, np.
CreatFromName(String name)ICreateFromCsvLine(String csvLine) - W razie potrzeby może zwrócić buforowany obiekt lub pochodną implementację.
Cons:
- Mniej wykrywalny, trudniejszy do przeglądania kod.
- Niektóre wzorce, takie jak serializacja lub odbicie są trudniejsze (np.
Activator<Foo>.CreateInstance())
Foo x = Foo.TryCreate(); if (x == null) { ... }). Obsługa wyjątku ctor to ( Foo x; try { x = new Foo(); } catch (SomeException e) { ... }). Podczas wywoływania normalnej metody wolę wyjątki od kodów błędów, ale przy tworzeniu obiektów TryCreatewydaje się czystsze.
Namei pisać CsvLine, niż wyrażać wymagania za pomocą nazw metod. Pozwoliłoby to na przeciążenie Utwórz. Używanie ciągów znaków w obu przypadkach może być uważane za „prymitywną obsesję” (zakładając, że nie dokonałeś tego wyboru ze znanych powodów wydajności). Sprawdź Object Calisthenics, aby uzyskać zabawny sposób na zbadanie tego.