2011-08-30 23 views
6

Widziałem wiele osób sugeruje, że należy ująć typy rodzajowe z klasy bliżej do domeny, na przykład Steve i Nat sugerują, że w Growing Object-Oriented Software, Guided by Tests:Kiedy powinieneś używać typów ogólnych?

Nasza zasada jest, że staramy się limit przechodzący przez typy z generycznymi [...]. Zwłaszcza gdy zastosujemy je do kolekcji, postrzegamy je jako formę duplikacji. Jest to wskazówka, że ​​istnieje pojęcie domeny, które powinno zostać wyodrębnione do typu.

W ogóle, kiedy jest to dobry pomysł, aby zrobić coś takiego ..

class PersonList : List<Person> 

.. a nie tylko za pomocą List<Person> bezpośrednio?

Odpowiedz

1

Ponieważ pozostawienie parametru typu takim, jaki jest, nie jest naprawdę SUCHĄ. Rozważmy taką klasę:

class Muffin { 
    List<string> _peopleWhoLikeMuffins = new List<string>(); 

    public Muffin(List<string> peopleWhoLikeMuffins) { 
     _peopleWhoLikeMuffins = peopleWhoLikeMuffins); 
    } 

    public void AddMuffinLiker(string p) { 
     _peopleWhoLikeMuffins.Add(p); 
    } 
} 

To bardzo krótki i zawiera tylko podstawowe funkcje, ale musiałem użyć string - genertic parametru Typ - cztery razy. I zawsze będzie tak samo. A jeśli zdecyduję się później zmienić typ, będę musiał wymienić wszystkie cztery wystąpienia.

W rzeczywistych scenariuszach mówimy o setkach, a nie 4. Więc nie jest to bezkompromisowe, aby zawsze je podsumować, ale zdecydowanie warto to rozważyć.

Mój przykład nie jest zbyt dobry (i to nie tylko z powodu głupich nazw), ale wpadł na pomysł - będziesz miał wiele deklaracji pól i zmiennych oraz tworzenie instancji i za każdym razem będziesz musiał przekazać parametr typu, który zawsze będzie taki sam w całej bazie kodu, chyba że inne klasy są również ogólne.

Kolejną zaletą jest to, że będziesz miał znacznie mniej pracy, jeśli będziesz potrzebować dodać do swojego zbioru dodatkowy stan/zachowanie.

To wszystko, co mówię, ja sam nie używam tego rodzaju abstrakcji bardzo często.

+3

W podanym przykładzie, bardziej sensownym byłoby uogólnienie Muffin na rodzajowy (i użycie go z ciągiem) niż zakodowanie na sztywno Listy , więc nie uważam tego za punkt na korzyść tworzenie określonych typów. – sinelaw

+0

@sinelaw: tak, wskazałem w mojej edycji, że przykład nie jest tak dobry i prawdopodobnie powinien też być generyczny – Dyppl

2

Nie zgadzam się z tą filozofią. List<Person> jest typem podobnym do PersonList. Pojęcie domeny listy osób jest również w niej zawarte. Jeśli mnie pytasz, lepiej używać generycznych tak bardzo, jak to tylko możliwe, chyba że użycie ich ogranicza (patrz poniżej) lub sprawia, że ​​kod jest trudny do zrozumienia. Na przykład funkcja, która działa na PersonList, będzie trudniejsza do uogólnienia niż ta, która działa na List<Person>, jeśli zauważysz, że robi coś ogólnego.

To powiedziawszy, szczególnie w Javie istnieje ograniczenie dotyczące leków generycznych, co czyni je mniej atrakcyjnymi. Ze względu na wymazywanie typów nie można w pełni wykorzystać generycznych metod, gdy zaangażowane są statyczne metody/elementy typu, i może być konieczne wyodrębnienie określonego typu, który nie jest generyczny, aby móc go używać do pewnych rzeczy. Najważniejsze jest to, że w Javie trzeba wyodrębnić określony typ w wielu przypadkach, jeśli pozwala to pozostać bezpiecznym typem.

3

To, czego szukasz, to operator typedef dla języka Java lub C#.

Niestety podejście do podklasowania nie jest dobrym zamiennikiem dla typedef.

Poniższy artykuł "Java theory and practice: The pseudo-typedef antipattern" wyjaśnia, dlaczego tak szczegółowo.

będę kopiować dosłownie zawarcia tego artykułu tutaj:

Motywacją dla antywzorzec projektowy pseudo-typedef jest prosta wystarczy - programiści chcą sposobem definiowania typu bardziej zwartych identyfikatorów, zwłaszcza leków generycznych utwórz identyfikatory typu więcej verbose. Problem polega na tym, że ten idiom tworzy ścisłe powiązanie między kodem , który wykorzystuje go i tych klientów kodu, uniemożliwiając ponowne użycie. Użytkownik może nie lubić gadatliwości ogólnych typów identyfikatorów, ale jest to nie sposób go rozwiązać.

Powiązane problemy