2016-04-14 46 views
5

Mam klasę, która wymaga sposobu na pobranie losowej wartości całkowitej z maksymalną wartością. Nie chcę, aby ta klasa była zależna od określonego sposobu pobierania tej losowej wartości (takiej jak system.random). Najlepiej byłoby, aby:C# Najlepsza praktyka: używanie delegata lub interfejsu jako zależności klasowej

(A) Za pomocą publiczną delegata (lub func)

public delegate int NextRandomInt(int maxValue); 

public class MyClass 
{ 
    public NextRandomInt NextRandomInt { get; set; } 

    public MyClass(NextRandomInt nextRandomInt) 
    { 
     NextRandomInt = nextRandomInt; 
    } 
} 

(B) Za pomocą publiczną interfejs

public interface IRandomIntProvider 
{ 
    int NextInt(int maxValue); 
} 

public class MyClass 
{ 
    public IRandomIntProvider RandomIntProvider { get; set; } 

    public MyClass(IRandomIntProvider randomIntProvider) 
    { 
     RandomIntProvider = randomIntProvider; 
    } 
} 

(C) Coś jeszcze razem.

Oba sposoby działają. Wydaje mi się, że użycie delegata byłoby prostsze i szybsze do wdrożenia, ale interfejs jest bardziej czytelny i może być łatwiejszy, gdy pojawi się iniekcja zależności.

+0

Sprawdź [wzór] (wzór) (http://www.dofactory.com/net/strategy-design-pattern) wzór projektu GOF. To może ci pomóc. – Fabjan

Odpowiedz

0

Z mojego punktu widzenia (jestem pewien) druga opcja z interfejsem jest najlepsza. Ta sytuacja jest typowym przykładem wzoru Strategy.

+0

Dlaczego twój interfejs jest najlepszy? A w jaki sposób powiązane są te dwa stwierdzenia? Strategię można wdrożyć za pomocą różnego rodzaju abstrakcji, w tym delegatów, więc nie widzę, w jaki sposób strategia implikuje korzystanie z interfejsu. –

+0

@ Mr.Putty Napisałem, że to jest mój punkt widzenia :) Preferuję interfejsy w takich przykładach, ponieważ do korzystania z delegata powinieneś utworzyć metodę w jakiejś klasie (i nie widzę jak ta klasa powinna być nazwana - 'RandomDelegates '?). I będzie piękniej tworzyć mały interfejs z konkretną klasą. Mam nadzieję, że mógłbym wyjaśnić mój pomysł. – user2216

1

To zależy od tego, ile pracy chcesz zaimplementować za pomocą uczestnika lub interfejsu.

Jeśli twój interfejs będzie miał tylko jedną lub nawet dwie metody, możesz użyć polecenia Func, aby wymusić to samo zachowanie. W przeciwnym razie użyłbym interface s.

Mark Seemann wyjaśnione właśnie to całkiem ładnie tutaj: link

Podsumowując stwierdza tak:

O ile to możliwe, wolę modelować swoje API z delegatów zamiast interfejsów jedna metoda, ponieważ daje mi to większą elastyczność i mniejszy kod infrastruktury.

Oczywiście, ta technika działa tylko tak długo, jak tylko konieczne jest zsumowanie pojedynczej metody. Gdy twoja abstrakcja potrzebuje drugiej metody, musisz wprowadzić odpowiedni interfejs lub, najlepiej, abstrakcyjną klasę bazową.

0
  1. Zastosowanie Interfejs jeśli myślisz, że nie może być inna realizacja NextRandomInt() mogą istnieć w systemie.
  2. Wybierz delegata, jeśli uważasz, że zostanie wykonany jako przyczyna zdarzenia lub wywołania zwrotnego.
    W przeciwnym razie po prostu użyj metody jako członka klasy. To zależy od Ciebie, jeśli chcesz, aby metoda była dostępna jako metoda instance lub static.