Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

КПЗ_Лаб5_c#

.pdf
Скачиваний:
5
Добавлен:
23.02.2016
Размер:
326.06 Кб
Скачать

PaymentClassification. Об'єкти HourlyCclassification

підтримують погодинну ставку, а також список об'єктів TimeCard. Об'єкти SalariedClassification підтримують місячну тарифну сітку. Об'єкти CommissionedClassification підтримують величини місячної зарплати, комісійних, а також перелік об'єктів SalesReceipt. Тут використано композицію взаємозв'язків для розглянутих випадків, оскільки справедливо покладатися, що об'єкти TimeCards і SalesReceipts повинні знищуватися після видалення запису працівника.

Рис. 6. Переглянута діаграма класів для програми розрахунків зарплати: базова модель

Також слід забезпечити можливість зміни методу платежу. На рис. 6 представлена реалізація цієї ідеї шляхом застосування шаблону Strategy, а також за допомогою генерування трьох різних типів класів PaymentMethod. Якщо метод Employee включає об'єкт

MailMethod, відповідному працівнику надсилається платіжний чек. Адреса, по якій відсилаються чеки, фіксується об'єктом MailMethod. Якщо об'єкт Employee включає об'єкт DirectMethod, платіж переводиться безпосередньо на банківський рахунок, який зберігається об'єктом DirectMethod. Якщо об'єкт Employee включає об'єкт HoldMethod, платіжні чеки відсилаються безпосередньо касирові. На рис. 6 також демонструється застосування шаблону Null Object щодо членства в організації. Кожному об'єкту Employee відповідає об'єкт Affiliation, що виступає у двох формах. Якщо об'єкт Employee включать об'єкт NoAffiliation, платіж не може адаптуватися відповідно до організації, відмінної від організаціїроботодавця. Якщо ж об'єкт Employee включає об'єкт UnionAffiliation, працівник платить членські внески, а також інші платежі, спрямовані на утримання організації. При цьому відповідні записи фіксуються об'єктом UnionAffiliation. Завдяки використанню перерахованих шаблонів досягається сумісність системи із принципом відкриття-закриття (OCP, Open-Closed Principle). Клас Employee закритий для змін методу платежу, класифікації платежів, а також членських внесків. Нові методи, способи класифікації, а також членські внески можуть додаватися в систему, не зачіпаючи клас Employee. На рис. 6 демонструється основна модель (архітектура). Ця модель представляє основу всього, що може виконувати система з розрахунків зарплати.

Платіжний день Варіант використання 7: виконання програми розрахунків

зарплати для одного платіжного дня

У результаті виконання транзакції Payday система здійснює пошук усіх працівників, оплата праці яких повинна бути зроблена до

зазначеної дати. Потім визначається величина оплати, після чого проводиться оплата відповідно до обраного методу платежу.

Payday <date>

Незважаючи на те, що зрозуміти призначення цього варіанта використання не становить особливої складності, визначити ступінь його впливу на статичну структуру, зображену на рис. 6, уже складніше. У цьому випадку потрібно відповісти на деякі питання. Поперше, яким чином об'єкт Employee одержує відомості про методи обчислення платежів? Якщо оплата праці працівника проводиться на погодинній основі, система підраховує кількість карток табельного обліку, множачи його на величину погодинної ставки. Якщо працівник одержує комісійні, система підраховує торговельні квитанції, виконуючи множення на величину комісійної ставки,

Рис. 7. Обчислення платежів а потім додаючи отриманий результат до суми базової зарплати. І де ж

проводяться всі ці обчислення? Ідеальним місцем є похідні класи PaymentClassification. Ці об'єкти включають записи, застосовувані при обчисленні величини оплати (причому можуть навіть включатися методи, що дозволяють розрахувати суму платежу). На рис. 7 показана діаграма співпраці, що описує все, про що розповідалося вище. Як тільки об'єкт Employee одержує запит на обчислення величини платежу, запит перенаправляється об'єкту

PaymentClassification. Фактично використовуваний у цьому випадку алгоритм залежить від типу об'єкта

PaymentClassification, який містить об'єкт Employee. На рис. 8— 10 демонструються три можливі в цьому випадку сценарії.

Рис. 8. Розрахунки зарплати для працівників, що одержують погодинну ставку

Рис. 9. Розрахунки зарплати для працівників, що одержують комісійні

Рис. 10. Розрахунки зарплати для працівників, що одержують фіксований оклад

Перші підсумки

На цей момент часу ми усвідомили, яким чином простий аналіз практичних випадків забезпечує підтримку багатого набору даних, а також дозволяє "заглянути усередину" системного проекту.

У пошуках базових абстракцій

З метою ефективного застосування принципу OCP випливає "улаштувати полювання" на базові абстракції, визначивши тих з них, які утворюють основу додатка. Досить часто ці абстракції не формулюються й навіть не згадуються у вимогах до даного додатка або до практичних випадків. Це пов'язане з тим, що у випадку опису базових абстракцій відбувається "розпухання" теоретичних і практичних випадків. Що ж можна сказати щодо базових абстракцій додатка з розрахунку зарплати? Давайте знову звернемося до опису вимог. У якості них виступають такі твердження, як "Деякі працівники працюють погодинно", "Деякі працівники одержують звичайну зарплату" і "Деякі працівники одержують комісійні". Усі ці висловлення можна узагальнити в таким чином: "Усі працівники одержують зарплату відповідно до різних схем". Відповідна абстракція формулюється в таким чином: "Усі працівники одержують зарплату". Модель класу PaymentClassification, наведена на рис. 7–10, добре виражає основну ідею розглянутої абстракції. Тому цю абстракцію можна вважати визначеною (нарівні з нашими користувацькими історіями).

Абстракція, пов'язана з календарним плануванням

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

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

Якщо (як і передбачається вимогами) розв'язання питань, пов'язаних з календарним графіком, буде передано класу PaymentClassification, це не забезпечить захист класу від змін у календарному графіку. Тому у випадку зміни політики платежів буде потрібно протестувати календарний графік. Після зміни календарних графіків слід протестувати політики платежів. У результаті можна запобігти можливому порушенню принципів OCP і SRP. Наявність зв'язку між політиками визначення календарного графіка й платежів приводить до появи помилок, коли зміна в конкретній політиці платежів приводить до складання некоректного календарного графіка для деяких працівників. Незважаючи на настільки видатну роль абстракції календарного планування, застосування аналізу за допомогою практичних випадків не дозволяє нам виявити її існування. У цьому випадку може допомогти ретельне вивчення вимог, а також консультації з користувачами майбутньої програми. До неприємностей може привести зайва довіра до інструментів і

процедур, а також недовіра до знань і досвіду фахівців. На рис. 11 і 12 показані статична й динамічна моделі абстракції календарного планування. І знову використовується шаблон Strategy. Клас Employee включає абстрактний клас PaymentSchedule. Існує три варіації класу PaymentSchedule, що відповідають трьом відомим календарним графікам, згідно з якими працівники одержують зарплату.

Рис. 11. Статична модель абстракції календарного планування

Рис. 12 Динамічна модель абстракції календрного планування

Методи платежів

Існує інше узагальнення, що випливає на основі сформульованих вимог: "Усі працівники одержують зарплату в результаті застосування певного методу платежу". У цьому випадку абстракцією є клас PaymentMethod. Саме ця абстракція відображена на рис. 6.

Внески

Сформульовані вимоги приводять до логічного виводу про те, що працівники платять внески за членство в певних організаціях. У цю

категорію включаються благодійні внески. Працівники також можуть автоматично відраховувати внески в професійні асоціації. Узагальнення в цьому випадку має такий вигляд: "Працівники можуть відраховувати внески різним організаціям, які автоматично оплачують представлені їм платіжні документи". Відповідну абстракцію в цьому випадку представляє клас Affiliation, який показаний на рис. 6. На цьому рисунку не показаний клас Employee, що містить більше одного класу Affiliation, а просто представлений клас NoAffiliation. Розглянутий нами проект недостатньо добре відповідає саме тій абстракції, у яку ми зараз будуємо. На рис. 13 і 14 показані статична й динамічна моделі, що представляють абстракцію Affiliation.

Рис. 13 Статична структура абстракції Affiliation.

Рис. 14 Динамічна структура абстракції Affiliation.

При роботі із переліком об'єктів Affiliation не використовується шаблон Null Object для вказання працівників, що не відраховуються

членські внески. Якщо є такі працівники то відповідний їм список членських внесків буде порожнім.