Как лучше организовать архитектуру проекта?

Пишу интернет магазин на php. Задумался, как организовать архитектуру проекта - классы, интерфейсы, наследование и т.д.

У фирмы есть один главный офис. Есть магазины, принадлежащие этой фирме.
В каждом магазине есть категории продуктов - мясо, молочные продукты, крупы.
В каждой категории есть продукты, например говядина.

Проблема в том, как лучше организовать структуру классов, чтобы не дублировать код и не нарушать другие принципы, принятые при разработке (солид, драй, кисс и т.д.)

У фирмы есть адрес - название, описание, изображение, страна, город, улица дом (описал поля класса).
У магазина есть - название, описание, изображение, страна, город, улица дом. Также есть способ оплаты картой/наличными.
Логично создать абстрактный класс с повторяющимися полями и унаследоваться от него. А в каждом дочернем классе добавить что нужно.

Но:
У категории продуктов есть название, описание, изображение. Но нет страны, города и т.д.
У товара есть название, описание, изображение.
Создавать ещё один абстрактный класс? Но тогда у этих 2х абстрактных классов будут дублироваться поля.
Причем эти поля несут одну и ту же смысловую нагрузку.

Параллельного множественного наследования в php нет. У интерфейсов полей нет.

Что делать?
  • Вопрос задан
  • 308 просмотров
Пригласить эксперта
Ответы на вопрос 5
402d
@402d
начинал с бейсика на УКНЦ в 1988
Меня заклюют, но интернет магазин и классы как вы их понимаете вообще не рядом.
Вы пытаетесь построить классы и связи между ними, чтобы избежать дублирования информации. Но смотрите. Сферический товар:
Просто лежит на витрине.
Участвует паралельно в акции.
Добавлен в корзину.
Стал частью заказа.
Часть фискального чека.
Архив.
Учетная система магазина.
Лежит на центральном складе.
Откупается у поставщика

и прочее и прочее. И в каждом случае у него своя цена
А первое желание у вас как я понимаю было сделать одно поле цена в классе товар ?
Ответ написан
ThunderCat
@ThunderCat Куратор тега PHP
{PHP, MySql, HTML, JS, CSS} developer
TL;DR без четкого понимания что и как будет работать что-то планировать или структурировать бесполезно. Нет универсального решения, надо делать под текущие задачи, с некоторой возможностью "маневра" в плане функционала.

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

У фирмы есть один главный офис. Есть магазины, принадлежащие этой фирме.
Фирма будет одна? Тогда нет смысла выделять его в отдельную сущность.

В каждом магазине есть категории продуктов - мясо, молочные продукты, крупы.
Во всех одинаковые? Или для каждого будет различный набор?

В каждой категории есть продукты, например говядина.
Тот же вопрос. Плюс еще у вас будет куча нюансов, типа - наличие/в резерве/на складе/в доставке/цены/скидки... И свойства разных товаров, которые у одних типов есть, а у других нет или сильно отличаются...
Ответ написан
Комментировать
@midia21
Олег уже по сути изложил эту мысль, но я ее перефразирую. Суть DRY, как мне кажется, не в том чтобы бороться с дублирующимся кодом, а в том, чтобы бороться с дублирующимися концепциями. Объясню: какой-то кусок кода в двух местах проекта может быть схожим - появляется искушение вынести его в одну функцию или класс, однако концепции (дальнейшие планы) на эти куски кода могут быть совершенно разными, и в будущем, по мере детализации первоначальной бизнес идеи, эти два куска кода станут совершенно не похожими друг на друга.

В данном случае: если у фирмы, магазина и категории продуктов изначально разный набор параметров, и в будущем есть опасения, что этот набор будет еще более различным, то не стоит эти параметры объединять в какой-то общий класс. Это можно было бы сделать, если, например, стояло бизнес-требования (концепция) реализовать унифицированный набор параметров для всех сущностей. В таком случае да - не стоило бы одну концепцию расчленять на разные части кодовой базы.

Если подытожить: не стоит бояться дублирующегося кода - стоит бояться дублирующихся концепций. В конечном счете не очень существенно сделать код короче убирая дублирующиеся куски - с эти справятся компиляторы или минимизаторы, которые кажется иногда обобщают дублирующийся код для оптимизации и в дальнейшем сводят весь огромный проект к одной длинной строке или бинарнику. С точки зрения архитектора по настоящему важно сделать код понятным и удобным для доработок. Это одна из основных целей программиста, имхо.
Ответ написан
Комментировать
gaparchi
@gaparchi
Логично создать абстрактный класс с повторяющимися полями и унаследоваться от него. А в каждом дочернем классе добавить что нужно.

Это как раз нарушение solid, а точнее lsp.

А однозначного ответа, тут быть не может, потому как слишком общий вопрос. Читайте DDD
Ответ написан
Комментировать
AgentSmith72
@AgentSmith72
JS - это моё хобби
Архитектура бывает двух типов:
  • На которой идёт быстрая разработка
  • Удобная для поддержки проекта

Нужно отделять бизнес логику от деталей. Для начала это может быть обращение к интерфейсу, и вам не важно что в дальнейшем у методов этого интерфейса поменяется реализация.

Нужно использовать сервисы и репозитории, в качестве абстракций к моделям. На практике это означает, что у контекста (например аккаунт) есть свой сервис - класс, где сосредоточена бизнес логика, и репозиторий - класс посредник для обращения к базовому репозиторию с методами запроса к базе данных.

Что касательно вашей ситуации, то вам следует опираться на принцип "Единственной ответственности", суть которого в том, что к каждого компонента может быть только одна причина для изменения.

Таким образом, причина для изменения логики работы с городами, не должна быть причиной изменения в коде, который работает с магазинами.

Лучше идти от большего к меньшему, то есть сначала использовать дублирование кода в разных контекстах, а потом провести рефакторинг и вынести все что нужно в отдельные классы.

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

Войдите, чтобы написать ответ

Похожие вопросы