Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Создание программного обеспечения для нательных компьютерных сетей и носимых систем. Учебное пособие.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
☆
Класс Термометр реализует Сенсор:
Метод получитьДанные():
// Логика получения данных от термометра
...
// Использование
функция использоватьСенсор(сенсор: Сенсор):
данные = сенсор.получитьДанные()
// Логика обработки данных
акселерометр = новый Акселерометр()
термометр = новый Термометр()
использоватьСенсор(акселерометр)
использоватьСенсор(термометр)
LSP):
Принцип Подстановки Барбары Лисков (Liskov Substitution Principle,
pseudo
Класс Фигура:
Метод рассчитатьПлощадь()
Метод отобразитьНаэкране()
Класс Прямоугольник наследует Фигура:
Поле: ширина
Поле: высота
Метод рассчитатьПлощадь():
Вернуть ширина высота
Метод отобразитьНаэкране():
// Логика отображения прямоугольника на экране
...
Класс Круг наследует Фигура:
Поле: радиус
61
Метод рассчитатьПлощадь():
Вернуть 3.14 радиус^2
Метод отобразитьНаэкране():
// Логика отображения круга на экране
...
// Использование
фигура = новый Прямоугольник()
фигура.ширина = 5
фигура.высота = 10
фигура.отобразитьНаэкране()
фигура = новый Круг()
фигура.радиус = 7
фигура.отобразитьНаэкране()
Принцип подстановки Барбары Лисков подразумевает, что объекты до­черних классов могут быть подставлены вместо объекта базового класса без изменения корректности программы. В приведенном примере и прямоугольник, и круг могут быть использованы там, где ожидается объект типа `Фигура`.
Принцип Инверсии Зависимостей:
pseudo
Интерфейс Сенсор:
Метод получитьДанные()
Класс Акселерометр реализует Сенсор:
Метод получитьДанные():
// Логика получения данных от акселерометра
...
Класс Термометр реализует Сенсор:
Метод получитьДанные():
// Логика получения данных от термометра
...
62
Класс УмныйГаджет:
Поле: сенсор (тип: Сенсор)
Метод использоватьСенсор():
данные = сенсор.получитьДанные()
// Логика обработки данных
// Использование
акселерометр = новый Акселерометр()
термометр = новый Термометр()
гаджетСАкселерометром = новый УмныйГаджет()
гаджетСАкселерометром.сенсор = акселерометр
гаджетСАкселерометром.использоватьСенсор()
гаджетСТермометром = новый УмныйГаджет()
гаджетСТермометром.сенсор = термометр
гаджетСТермометром.использоватьСенсор()
Принцип инверсии зависимостей позволяет создавать более гибкие си­стемы, где зависимости между компонентами строятся на абстракциях. В при­веденном примере `УмныйГаджет` зависит от интерфейса `Сенсор`, что позво­ляет ему использовать различные сенсоры без изменения кода.
Принципы SOLID:
1. Принцип Единственной Ответственности (Single Responsibility
Principle, SRP):
pseudo
Класс Датчик:
Метод получитьДанные():
// Логика получения данных от датчика
...
Класс ОбработчикДанных:
Метод обработатьДанные(данные):
// Логика обработки данных
...
63
// Использование
датчик = новый Датчик()
обработчик = новый ОбработчикДанных()
данные = датчик.получитьДанные()
обработчик.обработатьДанные(данные)
Принцип единственной ответственности предполагает, что класс должен иметь только одну причину для изменения.
В приведенном примере класс `Датчик` отвечает только за получение данных, а класс `ОбработчикДанных` – за их обработку. Это повышает модуль­ность и облегчает изменение функциональности каждого класса отдельно.
Принцип Открытости/Закрытости (Open/Closed Principle, OCP):
pseudo
Интерфейс Функциональность:
Метод выполнить()
Класс Функциональность1 реализует Функциональность:
Метод выполнить():
// Логика выполнения функциональности 1
...
Класс Функциональность2 реализует Функциональность:
Метод выполнить():
// Логика выполнения функциональности 2
...
Класс Клиент:
Поле: функциональность (тип: Функциональность)
Метод использоватьФункциональность():
функциональность.выполнить()
// Использование
функциональность1 = новая Функциональность1()
функциональность2 = новая Функциональность2()
64
клиент1 = новый Клиент()
клиент1.функциональность = функциональность1
клиент1.использоватьФункциональность()
клиент2 = новый Клиент()
клиент2.функциональность = функциональность2
клиент2.использоватьФункциональность()
Принцип открытости/закрытости подразумевает, что классы должны быть открыты для расширения, но закрыты для модификации.
В приведенном примере интерфейс `Функциональность` открыт для до­бавления новых классов, реализующих различные функциональности, без из­менения кода клиентского класса `Клиент` [5].
Принцип Замены Базового Класса на Производный (Liskov Substitution
Principle, LSP):
pseudo
Класс Фигура:
Метод рассчитатьПлощадь():
// Абстрактный метод рассчета площади
Класс Прямоугольник наследует Фигура:
Поле: ширина
Поле: высота
Метод рассчитатьПлощадь():
Вернуть ширина высота
Класс Квадрат наследует Фигура:
Поле: сторона
Метод рассчитатьПлощадь():
Вернуть сторона^2
// Использование
фигура1 = новый Прямоугольник()
фигура1.ширина = 5
65
фигура1.высота = 10
площадь1 = фигура1.рассчитатьПлощадь()
фигура2 = новый Квадрат()
фигура2.сторона = 7
площадь2 = фигура2.рассчитатьПлощадь()
Принцип замены базового класса на производный подразумевает, что объекты производного класса могут заменить объекты базового класса без нарушения функциональности программы. В приведенном примере объекты `Прямоугольник` и `Квадрат` могут быть использованы там, где ожидается объект типа `Фигура`.
Принцип Интерфейса-Разделения (Interface Segregation Principle, ISP):
pseudo
Интерфейс Функция1:
Метод выполнитьФункцию1()
Интерфейс Функция2:
Метод выполнитьФункцию2()
Класс РеализацияФункций реализует Функция1, Функция2:
Метод выполнитьФункцию1():
// Логика выполнения функции 1
...
Метод выполнитьФункцию2():
// Логика выполнения функции 2
...
Принцип интерфейса-разделения гласит, что клиенты не должны зависеть от интерфейсов, которые они не используют. В приведенном примере интер­фейсы `Функция1` и `Функция2` разделены, что позволяет классу `Реализа­цияФункций` реализовать только те методы, которые ему действительно необ­ходимым, избегая избыточных зависимостей.
66
Принцип Инверсии Зависимостей (Dependency Inversion Principle, DIP):
pseudo
Интерфейс Сенсор:
Метод получитьДанные()
Класс Акселерометр реализует Сенсор:
Метод получитьДанные():
// Логика получения данных от акселерометра
...
Класс Термометр реализует Сенсор:
Метод получитьДанные():
// Логика получения данных от термометра
...
Класс УмныйГаджет:
Поле: сенсор (тип: Сенсор)
Метод использоватьСенсор():
данные = сенсор.получитьДанные()
// Логика обработки данных
// Использование
акселерометр = новый Акселерометр()
термометр = новый Термометр()
гаджетСАкселерометром = новый УмныйГаджет()
гаджетСАкселерометром.сенсор = акселерометр
гаджетСАкселерометром.использоватьСенсор()
гаджетСТермометром = новый УмныйГаджет()
гаджетСТермометром.сенсор = термометр
гаджетСТермометром.использоватьСенсор()
Принцип инверсии зависимостей гласит, что модули верхнего уровня не должны зависеть от модулей нижнего уровня, оба должны зависеть от абстрак-
67
ций. В приведенном примере `УмныйГаджет` зависит от интерфейса `Сенсор`, что позволяет ему использовать различные сенсоры без изменения кода.
При разработке программного обеспечения для носимых технологий, включая умные часы, фитнес-трекеры и другие устройства, принципы SOLID и другие принципы ООП играют важную роль. Они обеспечивают создание гиб­кого, модульного и легко расширяемого кода, что особенно ценно в сфере раз­работки для разнообразных устройств и сенсоров [6].
Применение принципа единственной ответственности позволяет созда­вать отдельные компоненты, каждый из которых отвечает за конкретную функ­циональность (например, датчик, обработчик данных). Это улучшает читае­мость кода и упрощает тестирование [8].
Пара открытости/закрытости позволяет создавать расширяемые системы, добавление новых функциональностей без модификации существующего кода. Это важно в сфере носимых технологий, где появляются новые устройства и сенсоры.
Методология замены базового класса на производный поддерживает со­здание иерархии классов, отражающей разнообразие устройств и их функцио­нальности. Это позволяет использовать общие интерфейсы для работы с раз­личными устройствами [10].
Схема интерфейса-разделения помогает избегать избыточных зависимо­стей, что важно в контексте носимых технологий, где устройства и компоненты могут быть разнообразными.
В свою очередь метод инверсии зависимостей актуален в сфере носимых технологий, где различные устройства могут использовать разные сенсоры. Путем зависимости от абстракций (интерфейсов) вместо конкретных реализаций, обес­печивается гибкость и возможность замены компонентов без изменения кода.
Эти принципы, взятые вместе, способствуют созданию высококачествен­ного и устойчивого программного обеспечения для носимых технологий.

3.3. Обзор паттернов проектирования для эффективной разработки приложений

Паттерны проектирования представляют собой основные принципы и шаблоны, используемые разработчиками для создания эффективных, гибких и легко поддерживаемых программных систем. Они были представлены в книге
«Design Patterns: Elements of Reusable Object-Oriented Software» Гамма, Хелм,
68
Джонсон и Влиссидесом в 1994 году. Эти шаблоны предоставляют универсаль­ные решения для типичных проблем, возникающих в процессе разработки.
Один из наиболее широко используемых паттернов – это «Одиночка» (Singleton). Он обеспечивает создание только одного экземпляра класса и га­рантирует доступ к нему из любой точки программы. Это полезно, например, при создании объекта, отвечающего за работу с базой данных или настройками приложения.
Другим важным паттерном является «Фабричный метод» (Factory Method), который предоставляет интерфейс для создания экземпляра класса, но оставляет выбор конкретного класса наследникам. Это способствует гибкости системы, позволяя подклассам изменять тип создаваемых объектов.
1. Одиночка (Singleton):
class Singleton:
private static instance: Singleton
private constructor() {}
public static getInstance():
if (instance is null):
instance = new Singleton()
return instance
Объяснение:
Этот псевдокод демонстрирует реализацию паттерна «Одиночка». Класс Singleton имеет закрытый конструктор, чтобы предотвратить создание несколь­ких экземпляров. Метод getInstance возвращает существующий экземпляр или создает новый, если он еще не был создан.
2. Фабричный метод (Factory Method):
abstract class Creator:
public abstract factoryMethod(): Product
class ConcreteCreator1 extends Creator:
public factoryMethod():
return new ConcreteProduct1()
class ConcreteCreator2 extends Creator:
public factoryMethod():
69
return new ConcreteProduct2()
interface Product:
public abstract operation()
class ConcreteProduct1 implements Produc t :
public operation():
// реализация для продукта 1
class ConcreteProduct2 implements Produc t :
public operation():
// реализация для продукта 2
Объяснение
Здесь представлены абстрактный класс Creator с абстрактным методом factoryMethod, а также два конкретных класса ConcreteCreator1 и ConcreteCrea- tor2, реализующих этот метод для создания конкретных продуктов Concrete­Product1 и ConcreteProduct2
Паттерн «Стратегия» (Strategy) предоставляет возможность определить семейство алгоритмов, инкапсулировать каждый из них и делать их взаимоза­меняемыми. Это позволяет динамически изменять поведение объекта, не изме­няя его структуры.
«Наблюдатель» (Observer) – еще один важный паттерн, который опреде­ляет отношение «один ко многим» между объектами. Когда состояние одного объекта изменяется, все его зависимые объекты автоматически уведомляются и обновляются.
Паттерн «Адаптер» (Adapter) позволяет интерфейсу одного класса рабо­тать с интерфейсом другого класса. Это полезно при интеграции новых компо­нентов в существующую систему.
В обзоре паттернов проектирования важно отметить, что их применение способствует повышению модульности, гибкости и устойчивости кода.
Они помогают разработчикам создавать высококачественные приложе­ния, легко расширяемые и поддерживаемые в течение долгого времени.
Другим важным паттерном проектирования является «Компоновщик» (Composite), который позволяет клиентам обращаться к отдельным объектам и их композициям единым способом. Это упрощает работу с древовидными структурами, такими как графические интерфейсы или структуры документов.
70
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]