Як уникнути загальних назв для абстрактних занять?


10

Загалом, добре уникати таких слів, як "обробляти" або "обробляти", як частина імен рутини та імен класів, якщо ви не маєте справу з (наприклад) ручками файлів або (наприклад) unix-процесами. Однак абстрактні класи часто насправді не знають, що вони збираються робити з чимось, окрім, скажімо, обробки. У моїй теперішній ситуації у мене є "EmailProcessor", який входить у папку "Вхідні" та обробляє повідомлення з неї. Мені не зовсім зрозуміло, як назвати це більш точне ім'я, хоча я помітив, що виникає таке питання стилю:

  • краще ставитися до похідних класів як до клієнтів і називати базовим класом частину функціоналу, який він реалізує? Надає йому більше значення, але буде порушувати is-a. Наприклад, EmailAcquirer було б розумним ім'ям, оскільки він набуває для похідного класу, але похідний клас не придбає ні для кого.
  • Або просто дуже розпливча назва, оскільки хто знає, що робитимуть похідні класи. Однак "Процесор" все ще занадто загальний, оскільки він робить багато відповідних операцій, наприклад, вхід у систему та використання IMAP.

Будь-який вихід з цієї дилеми?

Проблема більш очевидна для абстрактних методів, в яких реально не можна відповісти на питання "що це робить?" тому що відповідь просто "все, що хоче клієнт".


Чи є у вас джерело (і якийсь контекст) для цього "загалом" претензії? Крім того, додаткове правило називання списку - не витрачайте час на пошуки ідеального імені, яке, мабуть, не існує. Якщо ви сумніваєтесь, дайте йому найкраще ім'я, додайте довший опис як коментар, де це визначено, якщо це необхідно, але ви завжди можете пізніше переробити фактор, якщо комусь не подобається ваш вибір або ідеальне ім’я раптом трапляється у вас, коли ви ' робиш щось інше.
Steve314

3
@ Steve314 - так, Steve McConnell, Code Complete, 1-е видання, розділ 4 або 5 про підпрограми. Обширна дискусія щодо називання в цих главах, по суті висновок, якщо у вас немає хорошого імені, ви, мабуть, не маєте гарної функції.
djechlin

невдача знайти хороше ім’я може здатися поганим знаком, але IMO вам слід знати, чи погана функція на основі самої функції. Рефакторинг лише тому, що англійська мова не була розроблена на замовлення для вашого проекту, є дещо складним. Ні, це не повсякденне питання, але ви вже вирішили, що маєте проблему.
Steve314

1
@ Steve314 Програмування стосується лише керування складністю, і якщо ваш мозок не може придумати слово для чогось, є досить хороший шанс, він не зможе керувати його складністю, коли він повинен робити такі речі, як використовувати його в більші пропозиції або як частина великих систем. Насправді не сміливе твердження сказати, що неможливість знайти хороше ім’я є великою причиною для паузи. Але це багато обговорюється в МакКоннелл, я б рекомендував прочитати ці дві глави хоча б, хоча вся книга варта читати в обкладинці до обкладинки.
djechlin

вимогам у Code Complete не слід довіряти. Я знаю про репутацію книг, але також знаю про це . Крім того, я досконало керував складнощами протягом століть - трапляються помилки, часто виникають помилки, але коли проблема йде не так, іноді проблема є функцією, яка є такою простою, що явно не може бути помилкою, але все одно .
Steve314

Відповіді:


10

Проблема не в назві, а в тому, що ви занадто багато кладете в один клас.

У вашому прикладі класу деякі частини є дуже конкретними (як будуть отримані листи). Інші частини дуже абстрактні (що ви будете робити з листами).

Краще це робити з окремими класами, ніж із спадщиною.

Я пропоную:

  • абстрактний MessageIterator, підкласифікований POPMailBoxDownloader

  • інший клас, який володіє POPMailBoxDownloader і робить щось із повідомленнями.


Це звучить абсолютно правильно. Це звучить так, як якщо ви опинитеся, що ви називаєте щось "processEvent" або клас "MessageProcessor", є хороший шанс, що ви могли б створити композицію замість деривації. У цьому випадку це компроміс, оскільки гнучкість для обслуговуючого персоналу може бути корисною, але клієнт буде роздратований, дивлячись, що саме робить кожна функція (більше, ніж підтримуючий).
djechlin

6

Якщо я не можу знайти гарне ім’я для класу, я пишу документацію вкладеного коду для класу. Він описує призначення класу в одному ароматі. Зазвичай я можу отримати гарне ім'я для класу з цього опису. Це також корисно для абстрактних занять.

Якщо опис класу - "Журнал у папку" Вхідні "та обробляє повідомлення з нього", я б запропонував "InboxProcessor" як назву класу. Якщо в похідному класі є "Вхід у папку" Вхідні "та переміщення спам-електронної пошти до папки спаму", я б вибрав "InboxSpamMover" як ім'я.

Я не бачу проблеми при використанні загальних імен на зразок "процесор", якщо вони відображають загальне призначення абстрактного класу.

Якщо у вас є проблеми з описом призначення класу в одному або двох ароматах, то у вас може виникнути проблема дизайну. Можливо, клас робить занадто багато і порушує Принцип єдиної відповідальності . Це стосується і абстрактних занять.


2

Якщо перефразовувати Френка Цаппу, це те, що воно є, і саме так слід називати. Ваш приклад просто не копається досить глибоко в тому, що відбувається обробка. Це чи EmailToTroubleTicketProcessor, EmailGrammarCorrectorчи це EmailSpamDetector?

Проблема більш очевидна для абстрактних методів, в яких реально не можна відповісти на питання "що це робить?" тому що відповідь просто "все, що хоче клієнт".

Це не зовсім так; питання, на яке ви не можете відповісти за щось абстрактне, - " як це робити, що робить?" тому що це залежить від реалізації. Якщо у EmailSenderкласу є DeliveryStatus deliver(Email e)метод, мається на увазі контракт про те, що реалізація візьме електронний лист, спробуйте доставити його та повернути деякий статус про те, як він пройшов. Вам не байдуже, підключається він до SMTP-сервера чи роздруковується, щоб він був прив’язаний до гомінного голуба до тих пір, поки реалізація зробить те, що обіцяли. Тези, які просто оцінюють цю обіцянку, так що реалізація може сказати: "так, я це роблю".


А як бути, коли кінцева функція в деякому сенсі є термінальною, тому абстрактний клас говорить "і це тут, зробіть з ним все, що завгодно?" наприклад, метод не має доступу до стану, недійсного типу повернення, без кидка.
djechlin

Це все одно те саме. Навіть якщо ваш метод є void doWhatYouDoWith(Email e), ви все одно можете назвати клас класом EmailDisposer, який є достатньо конкретним, щоб сказати, що він робить, але достатньо загальний, що залежить від реалізації. Хоча я думаю, що @KrisVanBael прибив це: якщо ви вдалися до чогось неоднозначного, під одним дахом може бути занадто багато.
Blrfl

0

Подумайте, чому погано вживати такі слова. Чи є вони описовими? Які слова є для опису класів? EmailBaseClass? Чи може це бути більш описовим, ніж скажімо EmailManager чи щось подібне? Ключовим є розуміння відповідного класу, тому знайдіть правильні дієслова чи іменники. Ставтесь до свого коду так, як це була поезія.


"EmailBaseClass", як іменування int age"ageInteger", ще гірше, оскільки я б очікував отримання чергових текстів електронної пошти, MIME-електронних листів тощо. Не потрібно abstractв першу чергу описувати те, що передує слову (це Java). Чи маєте ви якесь особливе розуміння для базової частини цього класу? І більше розуміння все ще не вирішує проблему називання чогось, що буде перетинати відносини, я можу або мати щось занадто розпливчасте, або занадто загальне, я не бачу виходу з цього, якщо б у мене не було більше розуміння того, щоб мати більше розуміння.
djechlin

@djechlin - рідкісні випадки, коли ageIntegerщось подібне насправді доречно. Угорська нотація - це скорочена версія з контексту, коли це траплялося багато. Безумовно, бувають випадки, коли вам може знадобитися щось в порядку ageNumericі ageStringв тому ж обсязі, причому вказівка ​​типу в імені є найпростішим і зрозумілішим способом розлучення.
Steve314,

@djechlin Мені особисто найпростіше працювати з кодом, на який я просто можу заглянути, щоб зрозуміти. Тобто імена говорять мені, з чим я працюю. Не потрібно знати, чи systemControllerє абстрактний базовий клас чи листок у величезній ієрархії. Звичайно, це може бути усунено за допомогою IDE (як я думаю, що це стосується більшості розробок Java?), Який може негайно інформувати користувача про зміст та структуру класу, так що насправді проникливі імена не можуть бути виправдані в подібній формі.
zxcdw
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.