Всем привет. Я опубликую часть вчерашнего вебинара чуть позже. А пока хочу вам показать разбор задачи с собеседования про фигуры.
Кейс. Задача:
Разработать систему для хранения и извлечения координат геометрических фигур (треугольник, круг, прямоугольник), изображённых на координатной плоскости.
У фигуры есть следующие характеристики:
• Тип фигуры (круг, треугольник, прямоугольник)
• Цвет заливки фигуры.
• Цвет бортика.
• Толщина бортика.
Первое, с чего я бы предложила начать, — это уточнение требований.
Важно понять:
• на каком уровне нужно проектирование: логическом или физическом;
• какие операции поддерживает система (CRUD, фильтрация и т.д.);
• есть ли ограничения по производительности и объёму данных.
Вы аналитик, не кидайтесь сразу строить ERD — сначала нужно зафиксировать требования.
Второе — определите основные сущности.
Например:
• Shape (Фигура) — общие данные;
• Circle (Круг);
• Rectangle (Прямоугольник);
• Triangle (Треугольник).
Дополнительно (если система расширяется или из выявленных требований):
• User (Пользователь);
• CoordinateSystem (Система координат).
Третье. Определите основные атрибуты сущностей.
Shape (общая сущность):
• id;
• type;
• fill_color;
• border_color;
• border_width.
Circle:
• center_x;
• center_y;
• radius.
Rectangle:
• x1, y1;
• x2, y2.
Triangle:
• x1, y1;
• x2, y2;
• x3, y3.
Небольшой вопрос. А что будете делать, если все три точки будут лежать на одной прямой? Получится треугольник? А если соединить все четыре точки прямоугольника так, чтобы получился бантик, вас устроит этот вариант?
Скорее нет.
Четвёртое. Задайте бизнес-правила.
Радиус круга всегда больше 0, у треугольника точки не лежат на одной прямой, у прямоугольника точки не совпадают. У прямоугольника ещё теоретически можно задать id следующей точки, чтобы не было бантиков.
Пятое. Выбор типа БД.
Кто вам сказал, что у вас обязательно реляционная БД?
Уточните у интервьюера или обоснуйте, какая БД лучше.
Сделаю допущение: используем реляционную БД.
Шестое. Выбор паттерна моделирования.
Я бы выбрала паттерн Table-per-Type (TPT), а не одну таблицу реализовывать, потому что:
• он обеспечивает расширяемость;
• позволяет избежать большого количества NULL-полей;
• даёт строгую типизацию данных.
Седьмое. Определение ключей.
Ключевая идея:
shape.id = circle.shape_id.
То есть:
• shapi.id— первичный ключ (PK);
• circle.shape_id — одновременно:
• PK;
• FK.
Аналогично для остальных таблиц.
Восьмое. Определение связей между сущностями.
Связи:
• Shape → Circle (1:1);
• Shape → Rectangle (1:1);
• Shape → Triangle (1:1).
При этом:
• одной записи в shape соответствует ровно одна запись в дочерней таблице в зависимости от типа.
Ниже код для UML-диаграммы (PlantUML):
@startuml
enum ShapeType {
CIRCLE
RECTANGLE
TRIANGLE
}
abstract class Shape {
+id: int
+type: ShapeType
+fill_color: string
+border_color: string
+border_width: float
}
class Circle {
+center_x: float
+center_y: float
+radius: float
}
class Rectangle {
+x1: float
+y1: float
+x2: float
+y2: float
}
class Triangle {
+x1: float
+y1: float
+x2: float
+y2: float
+x3: float
+y3: float
}
Shape
Кейс. Задача:
Разработать систему для хранения и извлечения координат геометрических фигур (треугольник, круг, прямоугольник), изображённых на координатной плоскости.
У фигуры есть следующие характеристики:
• Тип фигуры (круг, треугольник, прямоугольник)
• Цвет заливки фигуры.
• Цвет бортика.
• Толщина бортика.
Первое, с чего я бы предложила начать, — это уточнение требований.
Важно понять:
• на каком уровне нужно проектирование: логическом или физическом;
• какие операции поддерживает система (CRUD, фильтрация и т.д.);
• есть ли ограничения по производительности и объёму данных.
Вы аналитик, не кидайтесь сразу строить ERD — сначала нужно зафиксировать требования.
Второе — определите основные сущности.
Например:
• Shape (Фигура) — общие данные;
• Circle (Круг);
• Rectangle (Прямоугольник);
• Triangle (Треугольник).
Дополнительно (если система расширяется или из выявленных требований):
• User (Пользователь);
• CoordinateSystem (Система координат).
Третье. Определите основные атрибуты сущностей.
Shape (общая сущность):
• id;
• type;
• fill_color;
• border_color;
• border_width.
Circle:
• center_x;
• center_y;
• radius.
Rectangle:
• x1, y1;
• x2, y2.
Triangle:
• x1, y1;
• x2, y2;
• x3, y3.
Небольшой вопрос. А что будете делать, если все три точки будут лежать на одной прямой? Получится треугольник? А если соединить все четыре точки прямоугольника так, чтобы получился бантик, вас устроит этот вариант?
Скорее нет.
Четвёртое. Задайте бизнес-правила.
Радиус круга всегда больше 0, у треугольника точки не лежат на одной прямой, у прямоугольника точки не совпадают. У прямоугольника ещё теоретически можно задать id следующей точки, чтобы не было бантиков.
Пятое. Выбор типа БД.
Кто вам сказал, что у вас обязательно реляционная БД?
Уточните у интервьюера или обоснуйте, какая БД лучше.
Сделаю допущение: используем реляционную БД.
Шестое. Выбор паттерна моделирования.
Я бы выбрала паттерн Table-per-Type (TPT), а не одну таблицу реализовывать, потому что:
• он обеспечивает расширяемость;
• позволяет избежать большого количества NULL-полей;
• даёт строгую типизацию данных.
Седьмое. Определение ключей.
Ключевая идея:
shape.id = circle.shape_id.
То есть:
• shapi.id— первичный ключ (PK);
• circle.shape_id — одновременно:
• PK;
• FK.
Аналогично для остальных таблиц.
Восьмое. Определение связей между сущностями.
Связи:
• Shape → Circle (1:1);
• Shape → Rectangle (1:1);
• Shape → Triangle (1:1).
При этом:
• одной записи в shape соответствует ровно одна запись в дочерней таблице в зависимости от типа.
Ниже код для UML-диаграммы (PlantUML):
@startuml
enum ShapeType {
CIRCLE
RECTANGLE
TRIANGLE
}
abstract class Shape {
+id: int
+type: ShapeType
+fill_color: string
+border_color: string
+border_width: float
}
class Circle {
+center_x: float
+center_y: float
+radius: float
}
class Rectangle {
+x1: float
+y1: float
+x2: float
+y2: float
}
class Triangle {
+x1: float
+y1: float
+x2: float
+y2: float
+x3: float
+y3: float
}
Shape