You are on page 1of 8

ПРАКТИЧНА РОБОТА 8

Тема: Застосування інтерфейсів

Мета: Розуміння принципів створення, реалізації та застосування


інтерфейсів.

Час: 4 години

1. Завдання для самостійної підготовки

У процесі підготовки до заняття студент в обов’язковому порядку


повинен виконати наступні завдання:

 вивчити конспект лекцій;


 опрацювати літературу;
 занести у зошит для лабораторних робіт номер, тему, мету
лабораторної роботи.

2. Програма роботи

 ознайомитись з теоретичною частиною;


 виконати завдання пункту 4.2.2;
 скласти звіт та захистити роботу.

3. Теоретична частина

Інтерфейс - програмна/синтаксична структура, що визначає відношення


між об'єктами, які поділяють певну поведінкову множину і не пов'язані ніяк
інакше. При проектуванні класів, розробка інтерфейсу тотожна розробці
специфікації (безлічі методів, які кожен клас, який використовує інтерфейс,
повинен реалізовувати).

Інтерфейси, поряд з абстрактними класами і протоколами,


встановлюють взаємні зобов'язання між елементами програмної системи, що
є фундаментом концепції програмування за контрактом (Design by contract,
DbC). Інтерфейс визначає межу взаємодії між класами або компонентами,
специфікуючи певну абстракцію, яку здійснює реалізуюча сторона.

Інтерфейс в ООП є строго формалізованим елементом об'єктно-


орієнтованої мови і широко використовується в вихідному коді програм. [1]
4. Порядок виконання лабораторної частини

4.1. Оснащення робочого місця:

 методичні вказівки до виконання лабораторної роботи;


 конспект лекцій з дисципліни;
 комп’ютер з операційною системою Microsoft Windows;
 середа розробки Microsoft Visual Studio.

4.2. Програма виконання лабораторної частини

4.2.1. Контрольний приклад

Завдання 1. Напишіть інтерфейс Converter для конвертації температури з


градусів за Цельсієм в градуси за Кельвіном та Фаренгейтом. [2]
using System;

public class Program


{
public static void Main()
{
double temperature = 23.5;
string type = "Fahrenheit";

Converter converter = Select(type);


Console.WriteLine(converter.getConvertedValue(temperature));
}

static Converter Select(string type)


{
switch (type)
{
case "Celsius":
Console.WriteLine("Celsius");
return new CelsiusConverter();
case "Kelvin":
Console.WriteLine("Kelvin");
return new KelvinConverter();
case "Fahrenheit":
Console.WriteLine("Fahrenheit");
return new FahrenheitConverter();
default: throw new ArgumentException("Argument Exception");
}
}
}

interface Converter {
double getConvertedValue(double baseValue);
}

class CelsiusConverter : Converter {


public double getConvertedValue(double baseValue) {
return baseValue;
}
}
class KelvinConverter : Converter {
public double getConvertedValue(double baseValue) {
return baseValue + 273.15;
}
}

class FahrenheitConverter : Converter {


public double getConvertedValue(double baseValue) {
return 1.8 * baseValue + 32;
}
}

Завдання 2. Використовуючи фабричний метод визначити інтерфейс для


створення об'єктів конвертерів температури з градусів за Цельсієм в градуси
за Кельвіном та Фаренгейтом. [3]

Фабричний метод (Factory Method) - це патерн, який визначає


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

Патерн треба застосовувати:

 Коли заздалегідь невідомо, об'єкти яких типів необхідно


створювати.
 Коли система повинна бути незалежною від процесу створення
нових об'єктів і розширюватися: в неї можна легко вводити нові
класи, об'єкти яких система повинна створювати.
 Коли створення нових об'єктів необхідно делегувати з базового
класу класам спадкоємцям.

Формальне визначення патерну на мові C# може виглядати наступним


чином:

 Абстрактний клас Product визначає інтерфейс класу, об'єкти якого


треба створювати.
 Конкретні класи ConcreteProductA і ConcreteProductB
представляють реалізацію класу Product. Таких класів може бути
безліч.
 Абстрактний клас Creator визначає абстрактний фабричний метод
FactoryMethod(), який повертає об'єкт Product.
 Конкретні класи ConcreteCreatorA і ConcreteCreatorB - спадкоємці
класу Creator, що визначають свою реалізацію методу
FactoryMethod(). Причому метод FactoryMethod() кожного окремого
класу-творця повертає певний конкретний тип продукту. Для
кожного конкретного класу продукту визначається свій конкретний
клас творця.

Таким чином, клас Creator делегує створення об'єкта Product своїм


спадкоємцям. А класи ConcreteCreatorA і ConcreteCreatorB можуть
самостійно вибирати який конкретний тип продукту їм створювати.

Тепер розглянемо на реальному прикладі:


using System;

public class Program


{
public static void Main()
{
double temperature = 23.5;
string type = "Kelvin";
object[] obj = new object[]{2, 4, 6}; // деякі параметри

Converter converter = Select(type, obj);


Console.WriteLine(converter.getConvertedValue(temperature));
}
// припустимо нам необхідно передавати якісь параметри в клас-творець
// можна визначити будь-який інший спосіб передачі параметрів
static Converter Select(string type, params object[] obj)
{
switch (type)
{
case "Celsius":
Console.WriteLine("Celsius");
return new CelsiusCreator(obj).factoryMethod();
case "Kelvin":
Console.WriteLine("Kelvin");
return new KelvinCreator(obj).factoryMethod();
case "Fahrenheit":
Console.WriteLine("Fahrenheit");
return new FahrenheitCreator(obj).factoryMethod();
default: throw new ArgumentException("Argument Exception");
}
}
}

abstract class Creator {


abstract public Converter factoryMethod();
}
class CelsiusCreator : Creator {
object[] obj;

public CelsiusCreator(object[] obj) { this.obj = obj; }

public override Converter factoryMethod(){


CelsiusConverter cc = new CelsiusConverter();
// застосуємо ці параметри
cc.ParamOne = (int)obj[0];
cc.ParamTwo = obj[1].ToString();
return cc;
}
}

class KelvinCreator : Creator {


object[] obj;

public KelvinCreator(object[] obj) { this.obj = obj; }

public override Converter factoryMethod(){


KelvinConverter kc = new KelvinConverter();
return kc;
}
}

class FahrenheitCreator : Creator {


object[] obj;

public FahrenheitCreator(object[] obj) { this.obj = obj; }

public override Converter factoryMethod(){


FahrenheitConverter fc = new FahrenheitConverter();
return fc;
}
}

abstract class Converter {


abstract public double getConvertedValue(double baseValue);
}

class CelsiusConverter : Converter {


public int ParamOne { get; set; }
public string ParamTwo { get; set; }

public override double getConvertedValue(double baseValue) {


Console.WriteLine("ParamOne: " + ParamOne);
Console.WriteLine("ParamTwo: " + ParamTwo);
return baseValue;
}
}

class KelvinConverter : Converter {


public override double getConvertedValue(double baseValue) {
return baseValue + 273.15;
}
}

class FahrenheitConverter : Converter {


public override double getConvertedValue(double baseValue) {
return 1.8 * baseValue;
}
}
Плюс такого підходу в більшій гнучкості, ми відходимо від створення
об'єктів конкретних класів, конкретних реалізацій і працюємо з об'єктами на
рівні інтерфейсів. Потім програму буде легше оновлювати і розширювати.

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

4.2.2. Самостійна робота

Завдання 1. Опрацювати теоретичну частину лабораторної роботи.

Завдання 2. Створити консольний проект та виконати контрольний приклад.

Завдання 3. Змінити код Завдання 4 Лабораторної роботи №2


використовуючи інтерфейс замість абстрактного класу.

Завдання 4. Змінити код Завдання 2 контрольного прикладу замінивши


класи-творці узагальненим інтерфейсом.

Реалізація класів-творців дозволяє додавати у код створення окремих


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

Таким чином, замість створення окремих класів-творців для кожного


класу-продукту ми можемо використовувати лише один клас-творець, який
буде повертати об'єкт необхідного нам класу-продукту.

Завдання 5. Створіть метод fillArray, який в якості параметрів приймає масив


типу int та об'єкт клау, що реалізує інтерфейс ICalc, який містить один метод
calc.

Метод fillArray має повертати новий масив типу int, який заповнюється
за допомогою методу calc конкретного класу.

Логіку методів calc реалізувати на власний розсуд.


Приклад діаграми класів:

Також необхідно реалізувати відстежування виняткових ситуацій.


Наприклад, ділення на нуль.
СПИСОК ЛІТЕРАТУРИ

1. Wikipedia, the free encyclopedia [Електронний ресурс]. - Режим


доступу: https://www.wikipedia.org/

2. Хабр [Електронний ресурс]. - Режим доступу: https://habr.com

3. Metanit.com «Язык программирования C# и платформа .NET»


[Електронний ресурс]. - Режим доступу: https://metanit.com/

You might also like