2012-06-20 16 views
26

Zastanawiam się nad najlepszą praktyką tutaj. Czy w przypadku metody fabularnej dobrą metodą jest zwracanie wartości null, jeśli nie można jej utworzyć? Oto przykład:Czy metoda fabryka zwraca wartość NULL?

ICommand command = CommandFactory.CreateCommand(args); 
if (command != null) 
    command.Execute(); 
else 
    // do something else if there is no command 

Alternatywą byłoby zwrócić NullCommand lub coś, myślę, ale to, co jest najlepsze praktyki?

Odpowiedz

31

Myślę, że jest potencjalnie uzasadnione dla metody fabryki, aby zwrócić null w niektórych sytuacjach, ale nie, jeśli jest to metoda o nazwie CreateCommand. Jeśli byłby to GetCommand lub FetchCommand, to może być w porządku ... ale metoda Create powinna rzucić wyjątek na niepowodzenie, sugerowałbym.

Czy naprawdę chcesz, aby powrócić null w tej sytuacji zależy od większego obrazu, oczywiście. (Czy istnieje rozsądna implementacja obiektu zerowego, którą możesz zamiast tego zwrócić, na przykład?)

+0

Zgadzam się z @Jon Skeet. Create implikuje konstruktor i nie oczekujesz wartości zerowej od jednego z nich, więc jest mało prawdopodobne, abyś sprawdził, czy to było to, co zrobił. –

+0

@ TonyHopkinson: Z drugiej strony, nie spodziewałbyś się wyjątku od konstruktora. –

+6

@TimSchmelter: Dlaczego nie? Absolutnie * oczekiwałbym wyjątku od konstruktorów w pewnych sytuacjach - 'FileStream' jest klasycznym przykładem ...lub czegokolwiek z parametrami, które mogą być nieprawidłowe w dowolnej formie, np. podając zerowe odwołanie do czegoś, co może wymagać odwołania o wartości innej niż zerowa. –

1

Zgadzam się z Jonem Skeetem. CreateCommand wyraźnie oznacza konstrukcję.

Jeśli nie wygeneruje Exception, a następnie w tym scenariuszu bym osobiście pójść z realizacją NullCommand, aby uniknąć instrukcje warunkowe we wszystkich konsumentów i możliwe NullReferenceException błędów.

3

Powrotu null w tym przypadku spowoduje, że Twoja metoda trudniejsze w użyciu; klienci muszą mieć świadomość niejawnego błędu. Zamiast wyrzucać wyjątek, a można również zapewnić osobne sposób klientów do testowania tego warunku:

if (CommandFactory.CanCreate(args)) { 
    ICommand command = CommandFactory.Create(args); 
    command.Execute(); 
} 

Albo dokonać instantiatable fabryce; co byłoby lepiej, gdyby trzeba pre-proces args:

CommandFactory factory = new CommandFactory(args); 
if (factory.IsValid()) { 
    ICommand command = factory.Create(); 
    command.Execute(); 
} 

Interfejs fabryki teraz jasno i wyraźnie stwierdzić, że stworzenie może się nie powieść, ale nadal wymaga klienta do korzystania z metody sprawdzania. Inną opcją jest taka:

ICommand command; 
if (CommandFactory.TryCreate(args, out command)) { 
    // creation succeeded ... 
} 
+0

_ "prawdopodobnie się nie powiedzie, jeśli nie sprawdzą wartości NULL" _ Ponieważ C# nie obsługuje sprawdzonych wyjątków (w przeciwieństwie do java), klienci mogą również nie działać, jeśli nie obsługują tego wyjątku, więc to nie jest silny argument (imho) . –

+1

@TimSchmelter: Poprawiłem moje sformułowanie w odniesieniu do tego wyrażenia ... Mam nadzieję, że mój pogląd jest teraz jaśniejszy. –

0

To ma sens tylko do powrotu Null czy jest jakiś powód, dla którego chcesz chcą użytkownik musiał sprawdzić dla wartości null za każdym razem nazywa Utwórz. Normalnie, którą należy rozważyć następujące doskonale ważnego wzorca użytkowania:

var obj = MyFactory.CreateThing(); 
obj.DoSomething(); 

Ale co pan proponuje jest zmuszenie następujący wzór wykorzystania:

var obj = MyFactory.CreateThing(); 
if (obj == Null) { 
    // Handle null condition 
} else { 
    obj.DoSomething(); 
} 

Normalnie Null scenariusz oznaczałby niektóre rodzaj niepowodzenia, w którym to przypadku wyjątek najprawdopodobniej miałby największy sens. Ale ostatecznie jesteś tutaj twórcą muzyki i musisz zdecydować, co jest rozsądne w świecie, który budujesz.

Powiązane problemy