Перейти к основному содержимому
  1. Rust/

Архитектурный проект на Rust: Проектирование автоматизированной системы заботы о питомцах (PetCare Hub)

1043 слова·5 минут· loading · loading · · ·Rust-middle Черновик
О Rust - Эта статья часть цикла.
Статей прочитано 0/58
0%
📚 Введение и дополнительные материалы
🟢 Начальный уровень (Rust-basic)
Не прочитана
🔵 Средний уровень (Rust-middle)
36 Архитектурный проект на Rust: Проектирование автоматизированной системы заботы о питомцах (PetCare Hub) (текущая)
Не прочитана

Введение
#

Мы прошлись по фундаменту языка Rust: от управления памятью (RAII и Box), умных указателей (Rc, Weak, Arc) и внутренней мутабельности (Cell, RefCell, Mutex) до коллекций, итераторов и генераторов кода на макросах.

Настало время соединить все эти элементы в единый практический архитектурный проект!

Мы спроектируем систему PetCare Hub — автоматизированный комплекс управления заботой о питомцах (кошках, собаках, птицах). Система должна отслеживать состояние здоровья, управлять автоматическими кормушками и поилочками, обрабатывать датчики телеметрии в параллельных потоках и расставлять приоритеты экстренным вызовам ветеринара.


1. Доменная модель и гетерогенный полиморфизм
#

В реальном мире животные имеют разный рацион и правила ухода. В Rust мы описываем общее поведение через типаж PetAction.

Так как мы не знаем заранее, сколько кошек или собак зарегистрирует пользователь, мы используем динамическую диспетчеризацию (Trait Objects) в виде Box<dyn PetAction>. Это обеспечивает гибкое хранение разного поведения в едином векторе без необходимости жесткого связывания типов на этапе компиляции.

А для быстрой регистрации новых карточек животных мы используем декларативный макрос pet_profile!.

Исследуйте доменную модель в интерактивных слайдах:

Доменная модель и Trait Objects
Шаг 1/2
 1// Шаг 1: Доменная модель и полиморфизм через Trait Objects (dyn PetAction)
 2trait PetAction {
 3    fn name(&self) -> &str;
 4    fn perform_care(&self) -> String;
 5}
 6
 7struct Cat {
 8    name: String,
 9}
10
11impl PetAction for Cat {
12    fn name(&self) -> &str { &self.name }
13    fn perform_care(&self) -> String {
14        format!("Кот {}: выдать порцию сухого корма и запустить автопоилку", self.name)
15    }
16}
17
18struct Dog {
19    name: String,
20}
21
22impl PetAction for Dog {
23    fn name(&self) -> &str { &self.name }
24    fn perform_care(&self) -> String {
25        format!("Собака {}: выдать влажный корм и открыть умную дверцу в сад", self.name)
26    }
27}
28
29fn main() {
30    // Гетерогенная коллекция питомцев через Box<dyn PetAction>
31    let pets: Vec<Box<dyn PetAction>> = vec![
32        Box::new(Cat { name: "Барсик".to_string() }),
33        Box::new(Dog { name: "Рекс".to_string() }),
34    ];
35
36    println!("--- Автоматический уход за питомцами ---");
37    for pet in &pets {
38        println!("{}", pet.perform_care());
39    }
40}
41

1. Доменная модель и Trait Objects

  • Типаж PetAction описывает общий контракт поведения для всех питомцев.
  • Обертка Box<dyn PetAction> позволяет хранить разные типы животных в одном векторе.

2. Многопоточный хаб и Очередь Приоритетов
#

Фоновые потоки отслеживают показатели датчиков температуру и уровня воды. Чтобы безопасно делиться расписанием между потоками кормления и мониторинга, используется комбинация Arc<Mutex<Scheduler>>.

Почему именно BinaryHeap?
#

В приюте или дома могут происходить события разной важности. Обычная очередь VecDeque обработала бы плановое кормление кота раньше, чем экстренный сигнал о повышенной температуре у собаки.

Использование BinaryHeap (Max-Кучи) гарантирует, что задача с наивысшим приоритетом (например, priority: 100 — выдача медикаментов) всегда будет обработана первой, независимо от того, когда она попала в очередь!


3. Фильтрация датчиков через Кастомный Итератор
#

Вместо выделения временных векторов в куче при поиске тревожных сигналов, мы пишем собственный итератор CriticalAlertsIterator. Он производит отбор критических ситуаций лениво (Lazy Evaluation) «на лету» во время обхода.

Запустите примеры многопоточной синхронизации и кастомного итератора:

Многопоточность, Приоритеты и Итератор
Шаг 1/2
 1use std::cmp::Ordering;
 2use std::collections::BinaryHeap;
 3use std::sync::{Arc, Mutex};
 4use std::thread;
 5
 6// Элемент очереди ухода с приоритетом
 7#[derive(Eq, PartialEq)]
 8struct CareTask {
 9    priority: u32,
10    description: String,
11}
12
13impl Ord for CareTask {
14    fn cmp(&self, other: &Self) -> Ordering {
15        self.priority.cmp(&other.priority) // Max-Heap по приоритету
16    }
17}
18
19impl PartialOrd for CareTask {
20    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
21        Some(self.cmp(other))
22    }
23}
24
25fn main() {
26    // Многопоточный хаб управления приютом/кормушкой через Arc<Mutex>
27    let schedule = Arc::new(Mutex::new(BinaryHeap::new()));
28
29    // Фоновый поток добавляет регулярные кормления
30    let sched_clone = Arc::clone(&schedule);
31    let handle = thread::spawn(move || {
32        let mut lock = sched_clone.lock().unwrap();
33        lock.push(CareTask { priority: 10, description: "Плановое кормление в 18:00".to_string() });
34    });
35
36    // Главный поток регистрирует срочный прием лекарства
37    {
38        let mut lock = schedule.lock().unwrap();
39        lock.push(CareTask { priority: 100, description: "СРОЧНО: Выдать инсулин коту Мурзику".to_string() });
40    }
41
42    handle.join().unwrap();
43
44    println!("--- Выполнение задач ухода по степени важности ---");
45    let mut lock = schedule.lock().unwrap();
46    while let Some(task) = lock.pop() {
47        println!("Выполняется [Приоритет {}]: {}", task.priority, task.description);
48    }
49}
50

1. Многопоточный хаб и Очередь Приоритетов

  • Arc<Mutex<...>> обеспечивает безопасный доступ к планировщику из параллельных потоков.
  • BinaryHeap гарантирует, что критические медицинские задачи (приоритет 100) выталкиваются раньше планового кормления.

Итоги серии: Архитектурные паттерны Rust
#

Проектируя PetCare Hub, мы увидели истинную силу Rust:

  1. Гарантии памяти без GC: Умные указатели Box и Arc контролируют жизненный цикл объектов без паузы на сборку мусора.
  2. Безопасность потоков (Data Race Freedom): Компилятор запретит передавать данные в потоки без реализации типажей Send и Sync.
  3. Нулевая стоимость абстракций: Итераторы и макросы позволяют писать высокоуровневый код, который компилируется в максимально быстрый машинно-ориентированный код.

Проверь свои знания!
#

Пройдите финальный тест по архитектурным решениям в Rust:

Статья прочитана
Пожалуйста, оцените насколько статья была вам полезна и понятна
Цикл статей
О Rust - Эта статья часть цикла.
Статей прочитано 0/58
0%
📚 Введение и дополнительные материалы
🟢 Начальный уровень (Rust-basic)
Не прочитана
🔵 Средний уровень (Rust-middle)
36 Архитектурный проект на Rust: Проектирование автоматизированной системы заботы о питомцах (PetCare Hub) (текущая)
Не прочитана

Связанные статьи