Використання властивостей С # в додатку обміну валют в Visual C # (Sharp)

Досі тестовий код звертався до члена даних, як в наступному рядку коду:

elsExchangeRate – 12345

А члени даних реалізовувалися наступним чином:

public abstract class CurrencyTrader { public double ExchangeRate

}

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

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

Модифікація тестового коду для застосування властивостей

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

Модифікований клас CurrencyTrader, що надає ExchangeRate У кестве властивості С #, показаний на рис 63

Рис 63 Надання ExchangeRate в якості властивості С #

Щоб повністю ввести в оману тест, імя властивості має бути ідент імені раніше оголошеного члена даних Щоб уникнути колізії ідентікаторов, член даних ExchangeRate перейменований У _exchangeRate, а область видимості змінена з загальної (public) на приватну (private)

Властивості виглядають як методи без параметрів, але повертають значення Крім цього, кожне властивість повинна мати, принаймні, блок get або блок set (мут присутніми обидва блоку), які називаються getter (одержувач) і setter (уановщік) відповідно Властивості, що мають лише блок get, доступні тільки для читання А властивості, що мають тільки блок set, можна тільки встановлювати У контексті властивості є лише ключові слова get або set Ніякого друго коду додати не можна

Наступний оператор виконує код, визначений у блоці get, і отримує стояння з класу, привласнюючи його значення змінної:

value = elsExchangeRate

А наступна строчка виконує код, визначений у блоці set, і привласнює стан із змінної класу:

elsExchange = value

Блок кожного з цих двох типів має свої особливості Блок get повинен завжди повертати дані зухвалому коду, для чого потрібне застосування ключового слова return Блок set не зобовязаний робити нічого Але якщо необхідно знати, які

дані передаються властивості, можна використовувати змінну value, що не оголошується в коді, а просто мається на увазі Цю ситуацію можна рассматрать, начебто б мова С # надає нам значення змінної якимось чарами

Проблеми властивостей

Багато програмістів вважають, що використання властивостей сприяє распртраненію поганих навичок програмування, т к властивості роблять можливим доступ до внутрішнього стану обєкта У попередньому вихідному коді можна бачити, що член даних _exchangeRate має взаємно-однозначна відповідність з властивістю ExchangeRate Якщо викликає код привласнює значення властивості ExchangeRate, то відразу ж присвоюється значення і приватному члену даних

_exchangeRate Таким чином, оголюється, хоча і непрямим чином, внутрішній стан Як приклад розглянемо таку ситуацію Скажімо, ви рили спекти щось у електродуховці, і вам потрібно прогріти її до певної температури Найлегше зробити це за допомогою властивості Temperature слідуючи чином:

class Oven {

private int _temperature

public int Temperature { get {

return _temperature

}

set {

_temperature = value

}

}

}

Клас oven надає температуру, як властивість, яка є прямою посиланням на змінну temperature Код, що викликає клас oven, періодічкі запрошувати значення температури і вирішує, коли духовка розігрілася до необхідної температури

Отже, чи є клас oven в його поточній реалізації структурним класом На користувача класу oven покладається досить значна відповідальність у тому, що він повинен періодично запитувати значення температури і на основі отриманої відповіді вирішувати, прогрілася чи духовка до необхідної температури Кращим підходом було б визначити клас, який виконує цю роботу Тоді зухвалому коду потрібно було б тільки запитати у цього класу: Ти гов” Такий клас може виглядати наступним чином:

class Oven {

private int _temperature

public void SetTemperature(int temperature) {

_temperature = temperature

}

public bool AreYouPreHeated() {

/ / Перевіряємо, чи відповідає температура необхідної return false

}

}

Модифікована реалізація класу oven не надає члена даних

_temperature зовнішньому коду Також в даній ситуації член даних Temperature не представляє температуру духовки, але вказує верхню межу темперури розігріву Даний верхня межа встановлюється за допомогою методу SetTemperature () Перевірка готовності духовки здійснюється не отриманням її температури, а викликом методу AreYouPreheated () Викликає код отримує відповідь у вигляді значення true або false, що вказує стан нагріву духовки

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

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

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

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

За аналогією з раніше наведеним прикладом з доступом до різних кімнатах і обктам у вашому будинку, властивість Temperature можна порівняти з дозволом доста Наприклад, ви б не дозволили доступ до свого шафі будь-якого відвідувачеві, але ваша дружина або чоловік такий доступ мали б Будь-якому відвідувачеві вашого будинку нього робити у вашій шафі, але своїй дружині ви, швидше за все, довіряєте Часто стояння та його подання є питанням довіри і застосування правильної області видимості

ПРИМІТКА

У даному обговоренні властивостей і обєктно-орієнтованого проектування моєю метою є пояснити, що застосовно і те і інше, і у вас не повинно виникати упередження проти одного або іншого підходу Розробляючи тип, яка не оривает свій стан, ви розробляєте тип, який реалізує абстрактне Нерен А розробляючи тип, який дозволяє доступ до свого стану (до оеделенной ступеня), ви розробляєте тип для використання на нижньому технічному рівні Також слід памятати, що іноді внутрішній стан явлтся зовнішнім станом, як у прикладі з курсом валют Стан курсу валют не можна абстрагувати, т к воно є числом, використовуваним в обчисленнях

Джерело: Гросс К С # 2008: Пер з англ – СПб: БХВ-Петербург, 2009 – 576 е: ил – (Самовчитель)

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*