Реалізація ядра програми управління освітленням в Visual C # (Sharp)

У даному прикладі ядро ​​буде реалізовано у вигляді простого класу, що містить всю функціональність контролера Це означає, що окремі реалізації, теірованіе і додатки будуть взаємодіяти з одним класом

Далі наводиться приклад реалізації методу DimLights для плавного зниження рівня освітлення З ДОПОМОГОЮ класу LightingController:

public class LightingController {

public void DimLights(object grouping, double level) {

}

}

Даний метод застосовується таким чином: LightingController controller = new LightingController () object grouping = null

controllerDimLights(grouping, 050)

Код користувача явно створює екземпляр класу LightingController і також явно використовує метод DimLights () Але явне використання класу не дозволяє зімяти код контролера, не зачіпаючи при цьому користувачів, т к існує теая звязок між користувальницьким кодом і ядром Ось чому весь цей час я пртранно доводив важливість використання інтерфейсів, концепцій і реалізацій Але в даній ситуації з контролером абсолютно нічого з цієї теорії не примяти на практиці

Причина для використання класу випливає з прикладу в попередньому розділі і інтерфейсів ITaxDeduction і ITaxIncome У даному прикладі для кожного іерфейса була тільки одна реалізація, і жодну з цих реалізацій не позначений змінювати Як було пояснено в попередньому розділі, інтерфейси можна бо б представити у вигляді класів Ця ж логіка застосовна і до контролера Контролер, в аспекті сигнатури методів і властивостей, не зміниться особливо і буде реалізований тільки в одному екземплярі Таким чином, інтерфейс не є обовязковим, і використання класу є цілком прийнятним підходом, який і застосовується в даній чолі Але в деяких ситуаціях може бути бажаним реалізувати ядро ​​у вигляді інтерфейсу, а не класу Цей аспект раматрівается врозд Визначення ядра у вигляді інтерфейсу, а не класу далі в цьому розділі

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

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

Збереження колекції за допомогою звязаного списку

У прикладах в попередніх розділах колекції обєктів створювалися за допомогою Маів, як показано в наступному прикладі:

МуТуреП array = new MyType [10] array [0] = new MyType () array[2]   =  new MyType()

У цьому коді створюється масив, який може містити щонайбільше 10 елемеов (мутуре [ю]) Якщо нам буде потрібно зберегти більше число елементів, скем 20, то потрібно буде створити новий масив необхідного розміру і скопіювати вміст старого масиву в новий Однією з особливостей масиву є те, що значення його елементам присвоюються не обовязково в послідовному пядке У даному прикладі значення були присвоєні першому і третьому елементів масиву, залишивши нульовим значення другого елементу Таким чином, код, котий буде в циклі обробляти елементи масиву, повинен перевіряти їх на нулое значення Структура, створена попереднім кодом, показана на рис 82

Рис 82 Масив посилальних елементів

На рис 82 показаний дуже важливий аспект посилальних типів: елемент масиву Сержіо посилання на обєкт, а не сам обєкт Якби масив був звичайного типу, ТДА кожен з його елементів містив би весь обєкт, а не тільки посилання на нього

Масив з такою ж легкістю можна було б створити у вигляді обєкта, що містить декілька змінних, як показано в наступному коді:

class MyTypeArray { public MyType Elementl public MyType Element2

}

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

У звязаному списку окремі обєкти повязані один з одним і вказують на дрой довколишній елемент Елемент двонаправленого повязаного списку містить посилання тільки на два інших обєкта: наступний і попередній (Елемент однаправленного повязаного списку вказує тільки на один інший обєкт – на наступний)

У двунаправленном повязаному списку тип завжди буде мати два члени даних: Next і prev Кожен з цих членів даних вказує на інший елемент списку (рис 83) Для послідовної обробки елементів списку ми починаємо з лівого або з правого боку і переходимо до члена даних Next або prev, відповідно Далі наводиться приклад коду для такої обробки:

МуТуре curr = GetHeadOfList () while (curr = null) {

/ / Виконується небудь операція з curr curr = currNext

}

Рис 83 Структура двонаправленого повязаного списку

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

ПРИМІТКА

У більшості випадків використовується клас List, але також існує клас LinkedList Додаткову інформацію Про клас SystemCollectionGeneric LinkedList дл я версії NET можна знайти в документації  MSDN  30

Для ядра нашого застосування ми використовуємо двонаправлений список, щоб свати кімнати в набір груп

Створення звязаного списку

Можна створити окремий код для кожного з членів даних Next і prev двунравленного списку, але більш ефективним підходом буде визначити базовий клас Початкова структура класу BaseLinkedList (визначеного в бібліотеці LibLightingSystem) ВИГЛЯДАЄ ТЕКІМ чином:

public abstract class BaseLinkedList { private BaseLinkedList _next private BaseLinkedList _prev

public BaseLinkedList Next { get {

return _next

}

}

public BaseLinkedList Prev { get {

return _prev

}

}

}

Базовий клас BaseLinkedList оголошується абстрактним, щоб вказати, що іользованіе даного класу передбачає створення похідних від нього класів Члени даних Prev і Next є властивостями, які можуть тільки зчитувати значення приватних членів даних _prev і _next

Додавання та видалення елементів повязаних списків

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

public void Insert(BaseLinkedList item) { item_next = _next

item_prev = this

if (_next = null) {

_next_prev = item

}

_next = item

}

public void Removed {

9 Зак 555

if (_next = null) {

_next_prev = _prev

}

if (_prev = null) {

_prev_next = _next

}

_next = null

_prev = null

}

Метод insert () припускає, що обєкти вставляються в список, що містить Хя б один елемент Для застосування методу insert () потрібна, принаймні, наступний код:

BaseLinkedList singleElement = GetHeadOfList() BaseLinkedList anotherElement = CreateListElement() singleElementInsert(anotherElement)

При додаванні нового елемента першою справою членам даних _next і _prev обкта (тобто елементу), який додається в список, присвоюються значення

ПРИМІТКА

Зверніть увагу на те, як у методі insert () можна привласнити приватні член и данни х іншого примірника Як ми знаємо, приватна (private) область видимого і оачает, що тільки данни ї оголошений тип може обращатьс я до приватного м властивості м і методам У данно м випадку це правило не порушується, т до вона має на увазі, що тип може обращатьс я до приватних членам даних і приватним методам інших екземяро в даного типу

Після того як членам даних елемента були привласнені значення, елемент вставляється в список Для цього перенаправляється властивість _prev наступного елемента (якщо його значення не одно null), після чого властивості _next поточного елемента присвоюється вставляє обєкт

Метод Remove () виконує дії, зворотні діям методу insert () Снала перенаправляються властивості _next і _prev попереднього і наступного обсягів по (якщо їх значення не рівні null) Після цього членам даних _next і _prev видаляється елемента присвоюється значення null

ПРИМІТКА

ОГОЛОШЕННЯ е членів даних Prev і Next тільки дл я читання є загальноприйнято ї практикою Але дл я присвоювання їм значень необхідно застосовувати методи Примение властивостей тільки дл я читання є одним із способів запобігти спотворюючи внутрішнього стану у випадках, коли до нього необхідно надавати доступ

Джерело: Гросс К С # 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>

*

*