У мене є клас, який використовується для обробки платежів клієнтів. Усі, крім одного із методів цього класу, однакові для кожного замовника, за винятком способу, який обчислює (наприклад), скільки заборгував користувач. Це може сильно відрізнятися від замовника до замовника, і немає простого способу зафіксувати логіку обчислень у чомусь подібному файлі властивостей, оскільки може бути будь-яка кількість спеціальних факторів.
Я можу написати некрасивий код, який перемикається на основі customerID:
switch(customerID) {
case 101:
.. do calculations for customer 101
case 102:
.. do calculations for customer 102
case 103:
.. do calculations for customer 103
etc
}
але це вимагає перебудови класу щоразу, коли ми отримуємо нового замовника. Який кращий спосіб?
[Редагувати] "Дублікат" статті зовсім інший. Я не запитую, як уникнути заяви переключення, я прошу сучасний дизайн, який найкраще стосується даного випадку - який я міг би вирішити за допомогою перемикача, якби хотів написати код динозавра. Наведені приклади є загальними, а не корисними, оскільки вони, по суті, говорять "Ей, комутатор працює досить добре в деяких випадках, а не в інших".
[Редагувати] Я вирішив перейти з найкращим рейтингом (створити окремий клас "Клієнт" для кожного клієнта, який реалізує стандартний інтерфейс) з наступних причин:
Послідовність: я можу створити інтерфейс, який забезпечує всі класу клієнтів отримувати та повертати однаковий результат, навіть якщо він створений іншим розробником
Ремонтопридатність: весь код написаний однією і тією ж мовою (Java), тому більше нікому не потрібно вивчати окрему мову кодування, щоб підтримувати те, що повинно бути просто мертвою функцією.
Повторне використання: Якщо в коді виникає аналогічна проблема, я можу повторно використовувати клас клієнтів, щоб мати будь-яку кількість методів для реалізації "користувацької" логіки.
Ознайомлення: Я вже знаю, як це зробити, тому можу швидко зробити це та перейти до інших, більш гострих питань.
Недоліки:
Кожен новий клієнт вимагає компіляції нового класу клієнтів, що може додати певної складності в тому, як ми компілюємо та розгортаємо зміни.
Кожен новий клієнт повинен бути доданий розробником - особа, яка надає підтримку, не може просто додати логіку до чогось типу файлу властивостей. Це не ідеально ... але тоді я також не був впевнений, яким чином людина, яка працює в службі підтримки, зможе виписати необхідну бізнес-логіку, особливо якщо вона складна з багатьма винятками (як це можливо).
Це не буде добре, якщо ми додамо багато-багато нових клієнтів. Цього не очікується, але якщо це станеться, нам доведеться переосмислити багато інших частин коду, а також цю.
Для тих, хто цікавиться, ви можете використовувати Java Reflection для виклику класу за назвою:
Payment payment = getPaymentFromSomewhere();
try {
String nameOfCustomClass = propertiesFile.get("customClassName");
Class<?> cpp = Class.forName(nameOfCustomClass);
CustomPaymentProcess pp = (CustomPaymentProcess) cpp.newInstance();
payment = pp.processPayment(payment);
} catch (Exception e) {
//handle the various exceptions
}
doSomethingElseWithThePayment(payment);