Проблеми з уникненням занять з іменування Smurf з просторами імен


39

Я потягнув звідси термін smurf іменування (номер 21). Щоб врятувати будь-кого, хто не знайомий з проблемою, іменування Smurf - це акт префіксації купи пов’язаних класів, змінних тощо із загальним префіксом, щоб у результаті ви отримали " SmurfAccountViewпропуск a SmurfAccountDTOдо SmurfAccountController" тощо.

Я зазвичай чув це рішення - створити простір імен для smurf та скинути префікси smurf. Це, як правило, добре мені послужило, але я стикаюся з двома проблемами.

  1. Я працюю з бібліотекою з Configurationкласом. Це можна було назвати, WartmongerConfigurationале воно знаходиться в просторі імен Wartmonger, тому його просто називають Configuration. У мене також є Configurationклас, який можна було б назвати SmurfConfiguration, але він знаходиться в просторі імен Smurf, щоб це було зайвим. У моєму коді є місця, де Smurf.Configurationвідображається поряд Wartmonger.Configurationі вводити цілком кваліфіковані імена незграбно і робить код менш читабельним. Було б приємніше мати справу з SmurfConfigurationа (якщо це мій код, а не бібліотека) WartmongerConfiguration.

  2. У Serviceмоєму просторі імен Smurf у мене є клас, який можна назвати SmurfService. Serviceявляє собою фасад на вершині складної бібліотеки Смурфа, в якій працюють завдання Smurf. SmurfServiceздається, краще ім’я, тому що Serviceбез префіксу Smurf настільки неймовірно загальне. Я можу погодитись, що SmurfServiceце вже було загальне, марне ім'я, а відняття смурфу просто зробило це більш очевидним. Але це могло б бути названо Runnerі Launcherт. Д., І все одно мені буде "краще", SmurfLauncherтому що я не знаю, що Launcherробить, але я знаю, що SmurfLauncherробить. Ви можете стверджувати, що те, що Smurf.Launcherробити, має бути таким же очевидним, як іSmurf.SmurfLauncher, але я міг бачити `Smurf.Launcher як якийсь клас, пов’язаний із налаштуванням, а не клас, який запускає smurfs.

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


3
Чи Smurf.Launcherзапускає smurfs, чи він запускає SmurfJobs? Можливо, це можна було б назвати Smurf.JobLauncher?
Blorgbeard

2
Це запах коду, щоб назвати клас XService, XManager тощо. Це нічого не означають. Це як утиль. Якщо ви знімаєте назви файлів, все, що там, може бути або відсутні. Немає способу дізнатися, якщо ви не заглянете всередину. Я б перейменував його з SmurfService на щось інше повністю.
Даніель Каплан

1
Він фактично запускає SmurfJobs, або технічно запускає їх, щоб вони відповідали мові документації Smurf. У світлі цього і інші відповіді, я збираюся перейменувати SmurfServiceв SmurfJobRunner. Здається, номер 1 не має найкращого мовного агностичного рішення, як я очікував. Я можу побачити випадки, коли з цим SmurfConfigurationбуде правильний дзвінок, але в моєму випадку я вважаю, що Configurationце найкраще навіть із клопотами Wartmonger.Configuration.
Даніель Коверман

6
Я намагаюся зрозуміти, чому у вас є єдиний клас, який піклується про налаштування і Wartmongers, і Smurfs.
Дональні стипендіати

Чому Smurf.Configurationі SmurfConfigurationвідчувати себе по-різному? Звичайно, це не зайвий чар, чи не так? (Скоротіть, Configякщо проблема - це довжина.) Чи Smurf.Configurationє проблеми, які SmurfConfigurationне виникають ?
Пабло Н

Відповіді:


16

Ви піднімаєте кілька хороших балів.

  1. Що стосується наявності дублікатів класів, ви можете псевдоніми класів у C #. Наприклад, using ColorScheme = The.Fully.Qualified.Namespace.Outlook2007ColorScheme;див. Цю публікацію в StackOverflow . Ви не вказали свою мову програмування, але я зрозумів, що ви написали. Тож, де ви маєте справу з двома різними проектами, ви можете їх псевдонімом як SmurfConfigurationі WartmongerConfigurationщо звільнило б двозначність при споживанні обох класів.

  2. Оскільки послуга наражається на зовнішні додатки, я не бачу жодної проблеми в брендінгу послуги з назвою вашої програми, тому в цьому випадку SmurfServiceбуло б дійсно, оскільки воно фактично розмежовує групи послуг у споживчому додатку.

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


5
псевдоніми просто заплутують речі. Замість Smurf.Service тепер у вас є SmurfService = Smurf.Service. Так що ви, можливо, просто мали SmurfService як назву речі в першу чергу. У них є місце, але не для цього конкретного питання. Однак це, мабуть, найкраща відповідь на проблему, на яку немає відповіді :)
gbjbaanb

. C # в мені вийшов у моєму питанні, але я фактично зараз маю справу з java та org.apache.smurfville.wartmonger.configuration. Це, на жаль, виключає псевдоніми. 2 - вагомий момент, тому я збираюся продовжувати брендування Smurf для Сервісу.
Даніель Коверман

25

Суть просторів імен полягає в тому, що ви можете мати однойменні класи з різних бібліотек без їх зіткнення. Коли вам потрібно використовувати один і той же названий клас з обох, вам потрібно видалити неоднозначність, префіксуючи один або обидва з його простором імен.

Однак це не так вже й погано мати купу класів Smurf, якщо Smurf розповість вам щось конкретне про клас. Назви класів повинні бути достатньо описовими, щоб дати вам деяку інформацію про те, що робить клас.

      Session
       ^   ^
      /     \
DBSession   HttpSession

Точно так само DBSessionможе взяти DBRequestоб’єкт, який повертає DBResponseоб'єкт. HttpSessionТакож може працювати на HttpRequestі HttpResponseоб'єкти.

Це класи Smurf з метою.

Вони можуть жити в MyCompanyпросторі імен , але MyCompanyHttpSessionі MyCompanyDBSessionне дає вам ніякої більше інформації , ніж було раніше. У цьому випадку опустіть Smurf і зробіть його простором імен.

MyCompany.HttpSession

3

Раніше я протистояв цій самій точці плутанини, і зазвичай це справді питання про те, чи включаємо ми таку річ, яку вона називає.

Ви згадуєте SmurfConfigurationі WartmongerConfigurationяк потенційні види конфігурацій. Ви вказуєте, що ви видалили з його простору іменник (його вид), так що те, що вам залишилося, - це лише ваніль Configuration. Я б цього не робив.

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

Давайте уявимо, що у вашому додатку ви імпортуєте Strawberry.IceCreamклас, а потім починаєте інстанціювати безпосередньо з IceCream.

var ic = new IceCream(); //actually I'm strawberry ice cream

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

var sic = new StrawberryIceCream();
var cic = new ChocolateIceCream();

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


2

Це, безумовно, хороше правило: якщо у вас є загальний приставку для групи занять, вони, ймовірно, заслуговують на власну область імен. Щоб вирішити проблему тоді, коли вам потрібно використовувати аналогічно названі класи з двох просторів імен:

1) Пріоритетними є простори імен, хоча я б зробив це коротким, до речі, будь-якою природною абревіатурою, можливо, навіть лише 1 буквою:

using Sm = Smurf;
using W = Wartmonger;

Тоді завжди додайте префікс, де вони використовуються, і назвіть примірники відповідним чином:

Sm::Configuration smConf; 
W::Configuration wConf;

2) Псевдонім класу, як пропонується в іншій відповіді.

using SmConf = Smurf.Configuration;

3) Будь-яка бібліотека, над якою ви маєте контроль, не використовує термін "Конфігурація". Використовуйте тезаурус: наприклад, "Налаштування", "Модель", "Параметри". Це може бути більш значущим для контексту: Наприклад, якби Smurf був якимось модулем чисельного аналізу, який ви написали, можливо, "Параметри", було б краще для його налаштування. Використовуйте певну лексику, пов'язану з контекстом модуля, на вашу користь, щоб створити унікальні імена, що володіють унікальністю, навіть якщо їх змішують з іншими просторами імен. Я вважаю, що це може бути своєрідною відповіддю на питання 2 ОП.

4) Код Refactor, так що вам не доведеться змішувати використання конфігурації з двох різних місць. Детальніше про це вам належить.

5) Об’єднайте дві конфігурації в одну, перш ніж передати її у свій клас. Використовуйте комбінований клас конф для представлення:

struct Conf {
    SmurfConfiguration smurf;
    WartmongerConfiguation wart;
}

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


0

Здається дивним, що додавання одного пункту до імені вас турбує.

Wartmonger.Configuration configuration = Wartmonger.Configuration .new();

// vs

WartmongerConfiguration configuration = WartmongerConfiguration.new();

Якщо обидва Smurfта Wartmongerконфігурації використовуються разом в одному місці, але окремо вони використовуються в декількох місцях - тоді простор імен, безумовно, хороший підхід.

Маючи простір імен дасть можливість використовувати «чисті» імена у внутрішньому коді, де з префіксами ви в кінцевому підсумку з допомогою SmurfConfigurationвсередині SmurfService«s внутрішній код, який може стати дратує кожен раз, коли ви відкриєте цей код.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.