Чи вірний код C # (колекції об’єктів)?

Почнемо розгляд проблем з колекціями з широко поширеною прлеми: додавання всіх елементів в колекції Розглянемо наступний код: IList elements = new List ()

elementsAdd(1) elementsAdd(2) elementsAdd(3)

int runningTotal = 0

foreach (int value in elements) { runningTotal += value

}

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

обчислення суми необхідно знайти максимальне значення Такий код може виглядати наступним чином:

IList&ltint&gt elements = new List&ltint&gt()

elementsAdd(l) elementsAdd(2) elementsAdd(3)

int martValue = intMinValue

foreach (int value in elements) {

if (value &gt manValue) { martValue = value

}

}

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

IList&ltint&gt elements = new List&ltint&gt() elementsAdd(1)

elementsAdd(2) elementsAdd(3)

int ruimingTotal =0

foreach (int value in elements) {

runningTotal += value

}

ConsoleWriteLine(&quotRunningTotal (&quot + runningTotal + &quot)&quot)

int makValue = intMinValue

foreach (int value in elements) {

if (value &gt martValue) { martValue = value

}

}

ConsoleWriteLine(&quotMaximum value is (&quot + maxValue + &quot)&quot)

Інший варіант може бути таким: IList elements = new List () elementsAdd (1)

elementsAdd(2)

elementsAdd(3)

int runningTotal =0

int makValue = intMinValue

foreach (int value in elements) {

if (value &gt maXValue) { maatValue = value

}

runningTotal += value

}

}

Незалежно від використовуваного варіанту, проблема вирішується методом копіювання і вставки Для одного або двох примірників написати цикл foreach не так і слоо, але якби нам було потрібно використати код ітератора в десятці-півтора місць, це вже б було проблематичним Такий тип коду складніше піддається сопрожденію і розширення Одним із способів підвищення ефективності було б помістити код в абстрактний базовий клас, реалізований для обчислення почном загальної суми або знаходження максимального значення Далі привидиться приклад вихідного коду трьох таких абстрактних базових класів: IteratorBaseClasscs, RunningTotalcs і MaximumValuecs Для тестування кожен з цих класів можна помістити в окремий файл,

abstract class IteratorBaseClass { IList&ltint&gt Collection

protected IteratorBaseClass(IList&ltint&gt collection) { Collection = collection

}

protected abstract void ProcessElement(int value) public IteratorBaseClass Iterate() {

foreach (int element in Collection) { ProcessElement(element)

}

return this

}

}

class RunningTotal : IteratorBaseClass { public int Total

public RunningTotal(IList&ltint&gt collection) : base(collection) { Total = 0

}

protected override void ProcessElement(int value) { Total += value

}

class MaximumValue : IteratorBaseClass { public int MaxValue

public MaximumValue(IList&ltint&gt collection) : base(collection) { MaxValue = intMinValue

}

protected override void ProcessElement(int value) { if (value &gt MaxValue) {

MaxValue = value

}

}

}

static void Main(string[] args)

{

lList&ltint&gt elements = new List&ltint&gt() elementsAdd(1)

elemantsAdd(2) elementsAdd(3)

ConsoleWriteLine(&quotRunningTotal (&quot +

((new RunningTotal(elements)lterate()) as RunningTotal)Total + &quot) Maximum Value (&quot +

((new MaximumValue (elements) Iterated ) as MaximumValue) MastValue + &quot)&quot)

}

Модифікований код набагато довший, хоча користувальницький код (виделеий жирним шрифтом) – набагато коротший Проте, і цей код все ще нравільний Неправильність його полягає в тому, що проблему, вирішуване в ньому, можна вирішити іншим, більш простим, способом Так що, загалом, можна сказати, що завдання полягає в тому, що ми хочемо вирішити окрему певну техничку проблему, використовуючи для цього елегантний код, який не містить скопованние і вставлені повторювані фрагменти Рішення даної задачі з пощью делегатів, анонімних делегатів і лямбда-виразів розглядається в наступних розділах Ідея полягає в тому, щоб показати практичний прерій, в якому кожна можливість застосовується натуральним чином

ОЦІНКА ПЕРЕВАГ ПОВТОРНОГО ВИКОРИСТАННЯ КОДА

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

Спробуємо відповісти на це питання аналогією з будівництвом будинку Припустимо, що ви будуєте самі собі будинок і вам потрібно 50 крокв Крокви можна зібрати двома способами: укладаючи і зєднуючи індивідуально їх компоненти для кожного стріла, або ж можна спорудити спеціальний утримує шаблон для точної уадкі і зєднання компонентів Проблема полягає в тому, який з цих двох способів вибрати Якщо складання крокв без шаблону займе 3 дня, а з шаблоном 1 день, то начебто варто збирати крокви за допомогою шаблону Але не все так ПРТО, як здається Що якщо збірка самого шаблону вимагає 3 дня У такому випадку, час, заощаджений застосуванням шаблону, буде втрачено на створення шаблону Але якщо ви будуєте кілька будинків з однаковими кроквами, то тоді створення шаблону для їх складання буде виправдано

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

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

*

*