Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Решение задач: разбейте задачу на части

// Copyright 2025 Google LLC
// SPDX-License-Identifier: Apache-2.0

// Задача: реализация API для GUI

// Вопрос: какое минимальное полезное поведение нужно API для рисования?
pub trait DrawApi {
    fn arc(&self, center: [f32; 2], radius: f32, start_angle: f32, end_angle: f32);
    fn line(&self, start: [f32; 2], end: [f32; 2]);
}

pub struct TextDraw;

impl DrawApi for TextDraw {
    fn arc(&self, center: [f32; 2], radius: f32, start_angle: f32, end_angle: f32) {
        println!("arc of radius ")
    }

    fn line(&self, start: [f32; 2], end: [f32; 2]) { /* ... */
    }
}

// Вопрос: какой API будет удобен пользователям?

pub trait Draw {
    fn draw<T: DrawApi>(&self, surface: &mut T);
}

pub struct Rect {
    start: [f32; 2],
    end: [f32; 2],
}

impl Draw for Rect {
    fn draw<T: DrawApi>(&self, surface: &mut T) {
        surface.line([self.start[0], self.start[1]], [self.end[0], self.start[1]]);
        surface.line([self.end[0], self.start[1]], [self.end[0], self.end[1]]);
        surface.line([self.end[0], self.end[1]], [self.start[0], self.end[1]]);
        surface.line([self.start[0], self.end[1]], [self.start[0], self.start[1]]);
    }
}
  • Вы уже умеете разбивать задачи на части, но, скорее всего, привыкли опираться на методы в стиле ООП.

Это не кардинальное изменение: нужно лишь переставить порядок, в котором вы подходите к задачам.

  • Сначала попробуйте решить задачу с помощью обобщений и трейтов или перечислений.

    Требует ли задача определённого набора типов? Перечисление может оказаться самым чистым способом её решения.

    Действительно ли задаче важны конкретные детали задействованных типов или можно сосредоточиться на поведении?

  • Выстраивайте решение задач вокруг поиска минимального достаточного объёма знаний для реализации чего-либо.

    Существует ли уже трейт для этого случая? Если да, используйте его!

  • Если вам действительно нужны разнородные коллекции, используйте их! В Rust они существуют как инструмент не просто так.

    Остерегайтесь XY-проблемы: задача может казаться легче всего решаемой одним способом, но это решение может не затрагивать первопричину и привести к новым трудным проблемам в будущем.

    То есть прежде чем использовать динамическую диспетчеризацию с объектами трейтов, убедитесь, что она действительно нужна.

    Прежде чем использовать трейты, убедитесь, что они действительно нужны.