Ogólnie dobrze jest unikać słów takich jak „uchwyt” lub „proces” jako część rutynowych nazw i nazw klas, chyba że mamy do czynienia z (np.) Uchwytami plików lub (np.) Procesami unixowymi. Jednak klasy abstrakcyjne często nie wiedzą, co zamierzają z czymś zrobić, poza, powiedzmy, przetworzeniem. W mojej obecnej sytuacji mam „EmailProcessor”, który loguje się do skrzynki odbiorczej użytkownika i przetwarza z niej wiadomości. Nie jest dla mnie jasne, jak nadać temu bardziej precyzyjną nazwę, chociaż zauważyłem, że pojawia się następująca kwestia stylu:
- lepiej traktować klasy pochodne jako klientów i nazwać klasę podstawową częścią części, którą implementuje? Daje to więcej sensu, ale będzie naruszać is-a. Np. EmailAcquirer byłby rozsądną nazwą, ponieważ nabywa dla klasy pochodnej, ale klasa pochodna nie będzie pozyskiwać dla nikogo.
- Lub po prostu bardzo niejasne imię, ponieważ kto wie, co zrobią klasy pochodne. Jednak „Procesor” jest nadal zbyt ogólny, ponieważ wykonuje wiele istotnych operacji, takich jak logowanie i korzystanie z IMAP.
Jakiś sposób na wyjście z tego dylematu?
Problem jest bardziej widoczny w przypadku metod abstrakcyjnych, w których tak naprawdę nie można odpowiedzieć na pytanie „co to robi?” ponieważ odpowiedź brzmi: „cokolwiek klient chce”.
źródło
Odpowiedzi:
Problemem nie jest nazwa, ale to, że wkładasz zbyt wiele w jedną klasę.
W twojej przykładowej klasie niektóre części są bardzo konkretne (w jaki sposób będą otrzymywane maile). Inne części są bardzo abstrakcyjne (co zrobisz z mailami).
Lepiej to zrobić z oddzielnymi klasami niż z dziedziczeniem.
Sugeruję:
abstrakcyjny MessageIterator, podklasowany przez POPMailBoxDownloader
kolejna klasa OWNS POPMailBoxDownloader i robi coś z wiadomościami.
źródło
Jeśli nie mogę znaleźć dobrej nazwy dla klasy, piszę dokumentację kodu wbudowanego dla klasy. Opisuje cel zajęć jednym zapachem. Zwykle z tego opisu wywodzę dobre imię dla klasy. Jest to również pomocne w przypadku klas abstrakcyjnych.
Jeśli opis klasy to „Loguje się do skrzynki odbiorczej użytkownika i przetwarza wiadomości z niej”, sugerowałbym „InboxProcessor” jako nazwę klasy. Jeśli klasa pochodna ma „Loguje się do skrzynki odbiorczej użytkownika i przenosi spam e-mail do folderu ze spamem” jako opis, wybrałbym „InboxSpamMover” jako nazwę.
Nie widzę problemu podczas używania nazw ogólnych, takich jak „procesor”, jeśli odzwierciedla to ogólny cel klasy abstrakcyjnej.
Jeśli masz problemy z opisaniem celu klasy w jednym lub dwóch zapachach, możesz mieć problem z projektem. Może klasa robi za dużo i narusza zasadę pojedynczej odpowiedzialności . Dotyczy to również klas abstrakcyjnych.
źródło
Parafrazując Franka Zappę, jest tym, czym jest i należy go tak nazwać. Twój przykład po prostu nie wnika wystarczająco głęboko w to, jaki rodzaj przetwarzania się dzieje. Czy to an
EmailToTroubleTicketProcessor
, anEmailGrammarCorrector
czyEmailSpamDetector
?To nie do końca prawda; pytanie, na które nie można odpowiedzieć na coś abstrakcyjnego, brzmi „w jaki sposób robi to, co robi?” ponieważ jest to specyficzne dla implementacji. Jeśli
EmailSender
klasa maDeliveryStatus deliver(Email e)
metodę, istnieje domniemana umowa, że implementacja pobierze wiadomość e-mail, spróbuj ją dostarczyć i zwróć trochę statusu. Nie obchodzi Cię, czy łączy się on z serwerem SMTP, czy drukuje go w celu przywiązania do gołębia pocztowego, o ile implementacja spełnia obietnicę. Streszczenia jedynie określają ilościowo tę obietnicę, aby wdrożenie mogło powiedzieć „tak, robię to”.źródło
void doWhatYouDoWith(Email e)
, nadal możesz wywołać klasę anEmailDisposer
, która jest wystarczająco szczegółowa, aby powiedzieć, co robi, ale wystarczająco ogólna, jak to zależy od implementacji. Chociaż myślę, że @KrisVanBael go przybił: jeśli uciekłeś się do czegoś tak niejednoznacznego, może być zbyt wiele pod jednym dachem.Zastanów się, dlaczego tak źle jest używać takich słów. Czy są opisowe? Jakie są słowa, aby opisać klasy? EmailBaseClass? Czy może to być bardziej opisowe niż powiedzenie EmailManager lub coś podobnego? Kluczem jest wgląd w daną klasę, więc znajdź odpowiednie czasowniki lub rzeczowniki. Traktuj kod jak poezję.
źródło
int age
„ageInteger”, tylko gorzej, ponieważ spodziewałbym się z niego czerpać zwykłe wiadomości tekstowe, wiadomości MIME itp. Wabstract
pierwszej kolejności nie trzeba opisywać tego, co poprzedza słowo (jest to Java). Czy masz jakiś szczególny wgląd w podstawową część tej klasy? I więcej wglądu nadal nie rozwiązuje problemu nazwania czegoś, co będzie krzyżować związek, mogę mieć coś zbyt niejasnego lub zbyt ogólnego, nie widzę wyjścia z tego, chyba że miałbym więcej wglądu w posiadanie większego wglądu.ageInteger
coś takiego jest właściwe. Notacja węgierska to skrócona wersja z kontekstu, w którym wiele się wydarzyło. Oczywiście, są chwile, kiedy może trzeba coś wzdłuż liniiageNumeric
iageString
w takim samym zakresie, wraz ze wskazaniem rodzaju w nazwie będącej najprostszy i najczystszy sposób dwuznaczności.systemController
jest to abstrakcyjna klasa bazowa czy liść w ogromnej hierarchii. Oczywiście można temu zaradzić za pomocą IDE (jak przypuszczam, że tak jest w przypadku większości programów Java?), Które mogą natychmiast poinformować użytkownika o zawartości i strukturze klasy, tak że tak naprawdę wnikliwe nazwy nie mogą być uzasadnione w podobny sposób.