Чому модель дизайну заводських методів корисніша, ніж заняття та називати їх окремо?


32

З моделей дизайну "Банда з чотирьох" є метод "Фабрика":

class Factory(product)
  case product
  when a
    new A
  when b
    new B
  when c
    new C
end

new Factory(a)

Чому це більш корисно , ніж мати три класи, a, bі cта називаючи їх по окремо?


1
Що саме ви маєте на увазі? Чому б не приміркувати всіх трьох? Це ви маєте на увазі?
Ніл

1
@Neil Ні, у заводському зразку всі класи існують як брати і сестри. Навіщо викликати фабрику для опосередкованого доступу до класів a, b, c?
alt

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

2
Тому що під час проектування ви не знаєте, який із 3 класів потрібно інстанціювати.
MrWhite

2
@jk: Ні, це насправді не так. programmers.stackexchange.com/questions/81838/…
пдр

Відповіді:


54

Тому що ваш приклад недостатньо складний. Для такого простого сценарію навіть не має сенсу використовувати розширений зразок.

Але якщо для побудови A, B або C вам потрібно знати більше, ніж продукт, і ви не можете мати прямий доступ до цих знань, то це корисно. Потім ви використовуєте фабрику, щоб діяти як центр знань для виготовлення потрібних предметів.

Можливо, ці об'єкти потребують посилання на якийсь об'єкт X, який може надати фабрика, але ваш код у тому місці, де ви хочете побудувати A, B або C, не може або не повинен мати доступ до X. Можливо, коли у вас є X ви створюєте A і B, але якщо у вас тип Y, ви створюєте C.

Також врахуйте, що для створення деяких об’єктів може знадобитися 20 залежностей; що тоді? Поїздка на ці залежності залежно від місця, де вони не мають бути доступними, може бути проблематичним.


13
+1, щоб зрозуміти, що заводський зразок - це не завжди найкращий підхід.
Ніл

1
Тому що ваш приклад недостатньо складний. Для такого простого сценарію навіть не має сенсу використовувати розширений зразок. То що б ви зробили в цьому випадку? Вбудована умовна конструкція?
пдр

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

Візерунок називається фабричним методом з причини. Метод не повинен бути в іншому класі, щоб бути заводським методом (хоча це часто).
пдр

Я пропустив "Метод" у ньому, тож ти маєш рацію.
Матеуш

23

Заводський зразок, як правило, складніший за це. Завод вирішує певні критерії, який екземпляр створити / повернути. Натомість, коли ви не використовуєте фабрику, цей код ви б неодноразово використовували у кількох місцях вашого коду.

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


20

Шаблон «Фабричний метод» абстрагує процес прийняття рішення з класу викликів. Це має ряд переваг:

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

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

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

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

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


14

Ключові переваги фабрики - двічі:

  1. Місця, які потребують реалізації продукту, не повинні знати, як його побудувати. Фабрика зберігає цю інформацію.

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

  2. Місця, які потребують реалізації продукту, не потрібно знати на момент опису модуля (тобто, під час компіляції), що називається клас реалізації.

    Таким чином, aне потрібно мати нічого спільного A; "що будувати" можна описати з точки зору бажаних нефункціональних властивостей, а не лише назви. Це набагато гнучкіше.

Мінус полягає в тому, що там, де ви знаєте, що робити і як це зробити, ви отримуєте більшу складність, коли використовуєте фабрику. Однак виправити це просто: не використовуйте фабрику, коли це не має сенсу!


2

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

Отже, для мене заводський зразок - це як агентство найму. У вас є хтось, який потребуватиме змінну кількість працівників. Ця людина може знати інформацію, яка їм потрібна, у людей, яких вони наймають, але це все.

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

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

Люб'язно


1

Фабричний візерунок є найбільш зловживаним та зловживаним дизайном.

Я стикався з численними випадками, коли клас Factory зашифровується, коли простий конструктор був би адекватним.

Не використовуйте заводський клас, якщо: -

  • Ви залежите від зовнішнього ресурсу, але ще не знаєте, який саме ще.
  • Будівництво коштує дорого, і ви хочете побудувати один раз і повторно використовувати багато разів.
  • Конструювання нового екземпляра залежить від того, які екземпляри вже побудовані (наприклад, у вас може бути лише п’ять з'єднань; або, ви повинні використовувати номер з'єднання номер один більше останнього використовуваного номера).

0

Використовуйте заводський метод при створенні екземплярів підкласу та клієнтського коду не несе відповідальності за визначення конкретного підкласу.

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

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

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

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