anton_reut
@anton_reut
Начинающий веб-разработчик

Набросал структуру классов учебного сайта доски объявлений, как еще лучше распределить функционал?

В общем посидел над своим процедурным кодом и накидал пока что Классы и Функции к ним (без данных). Смотрю Елисеева, читаю Зандстру и "Объектно-ориентированное мышление" Вайсфилда.

Это только примерная принципиальная схема, каркас.
В данный момент получилось вот так:
(некоторые функции будут принимать другие объекты, да, "матрешка в матрешке")
// --------------- ВСЁ ЧТО КАСАЕТСЯ ПОЛЬЗОВАТЕЛЕЙ: -------------------

class User {
	public function getName(){
		// Отобразить имя
	}
	public function getPhone(){
		// Отобразить телефон
	}
}

class UserPersonalPage {
	// Личный кабинет. 
	public function displayMyAdverts(){
		// Показать мои объявления. 
		// Вызвать Объект MyAdverts, передать ему мой id для вывода моих объявлений
	}
	public function displayMyFavorites(){
		// Показать мои избранные. 
		// Вызвать Объект MyFavorites, передать ему мой id для вывода моих избранных объявлений
	}
	public function displayMyPersonalInfo(){
		// Показать мою персональную информацию - Имя, email, телефон
	}
	public function changeMyPersonalInfo(){
		// Изменить мою персональную информацию - Имя, email, телефон
		// Вызвать Объект UserService, передать ему мой id, вызвать метод изменения нужной информации
	}
}

 // --------------- ВСЁ ЧТО КАСАЕТСЯ ОБРАБОТКИ ПОЛЬЗОВАТЕЛЕЙ: -------------------

class UserService {
	
	public function addUser(){
		// Регистрация пользователя
	}
	public function deleteUser(){
		// Удаление пользователя
	}
	public function activateUser(){
		// Активация пользователя
	}
	public function changeUserPassword() {
		// Сменить пароль пользователю
	}
	public function changeUserName() {
		// Сменить имя пользователю
	}
	public function changeUserEmail() {
		// Сменить email пользователю
	}
	public function changeUserPhone() {
		// Сменить телефон пользователю
	}
}

class UserLoginLogoutService {
	// Вход и выход пользователей
	public function userLogin(){
		// Вход
	}
	public function userLogout(){
		// Выход
	}
}

 // --------------- ВСЁ ЧТО КАСАЕТСЯ ОБЪЯВЛЕНИЙ: -------------------

class AdvertCollection {
	// Список объявлений
	public function displayRecentAdverts(){
		// Показать последние добавленные объявления
	}
	public function displayPromotedAdverts(){
		// Показать объявления выведенные в топ платно
	}
}

class Advert {
	// Объявление детально
	public function displayAdvert(){
		// Показать объявление детально
	}
}

class AdvertFavorites {
	// Избранные объявления
	public function addAdvertToFavorites(){
		// Добавить объявление в мои избранные
	}
	public function displayFavorites(){
		// Показать мои избранные
	}
}

class MyAdverts {
	// Мои объявления
	public function displayMyAdverts(){
		// Показать все мои объявления
	}
}

Как еще, более грамотно, можно всё это распределить? Как бы вы сделали?
  • Вопрос задан
  • 851 просмотр
Решения вопроса 2
myks92
@myks92 Куратор тега PHP
Нашёл решение — пометь вопрос ответом!
Смотрите дальше курсы Елисеева. У него есть урок по проекту менеджеров. Где он разбивает все по паттерну CQRS. Вот ссылка на доменный слой https://github.com/ElisDN/demo-project-manager/tre...

У вас получается, что UserService это Handler или UserHandler, если вы держите это все в одной папке. Посмотрите структуру. Я сейчас так же делаю и это очень просто понять. В UseCase папки то, что нужно делать:
UseCase/User/Create
В ней Файлы:
Command.php
Handler.php
Form.php

Или так:
UseCase/User
В ней Файлы:
UserCreateCommand.php
UserHandler.php
UserCreateForm.php

Если касаемо вашего, то не нужно повторять название методов в классе. UseServise метод просто login, а не userLogin

Так же по названиям немного надо получше подумать. UserLoginOrLogoutServise удобнее назвать AuthServise...

Не понятно откуда столько методов с началом в названии display

Внедряйте репозиторий.
Ответ написан
h0w4rd
@h0w4rd
Python dev.
1. [класс User] я бы использовал названия "name" и "phone", все-же ясно что это.

2. [класс MyAdverts] ЗАЧЕМ? Можно сразу впихнуть в UserPersonalPage логику.

3. [класс AdvertFavorites], зачем? Эти методы в Advert впихнуть НАДО, это к тому классу относится.

4. [класс UserLoginLogoutService] Переименовать в UserAuthService хотяб. Или убрать методы в обычные функции. ООП ради ООП = зло.

5. [класс UserPersonalPage] Убрать "my" из названия методов. Оно ничего не несет, ведь ясно к чему оно относится.

6. [класс UserService] За такое я бы руки отбивал. Это все к объекту пользователя относится. Ведь user_service->changeUserName(user, "foo"); в разы хуже user->setName("foo");

7. Касается всего: зачем, к примеру называть метод "changeUserName" если можно просто "setName" или "setNickname" ну или "setUsername".

Прошу принять все серьезно и прочитать не между строк. Так вам же проще будет и всем кто ваш код использовать будет. Серьезно, чем проще тем лучше (ну, все-же упрощать не нужно вообще в максимум, в рамках разумного).
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@developer007
Городить кучу классов не надо. вообще не надо. Думаешь это круто смотрится? Handle хуяндле... начитаются всяких Елисеевых... возможно и круто, но поддерживать это говно такое себе.

сделай компоненты - т.е есть несколько сервисов и есть фасад, который агрегирует сервисы
https://refactoring.guru/ru/design-patterns/facade

component/User/Facade.php - здесь выносишь наружу методы которые ты хочешь использовать везде.
component/User/AuthenticateService.php - здесь методы регистрации, авторизации, выхода
component/User/SettingsService.php - здесь методы смены юзернейма и тд
component/User/Entity/User.php - сущность из БД
component/User/UserRepository.php - здесь методы работы с БП . В эти методы ты передаешь User.php

(мне нравится Service всегда дописывать, как вздумается вообщем. Главное чтобы понятно было другим людям)

делаешь еще компонент
component/Adv/Facade.php - здесь методы про объявления
и также делаешь внутренние сервисы.

Смотри чтобы не было цикличных зависимостей.
Постарайся использовать внешний EventListener - типа юзер первый раз авторизовался, выкидываешь это событие. Ловишь в компоненте Adv и создаешь ему демо объявление. Как пример.
Так ты будешь поддерживать слабую связанность.
Ответ написан
Комментировать
php666
@php666
PHP-макака
Я проектировал доску с нуля на ООП.
Я бы написал расширенный ответ, но лень.
Надо просто читать Фаулера, я говорил тебе 100 раз. Ты этого не делаешь, поэтому ты пишешь какую-то вроде отчасти и правильную вещь, но если разложить по полочкам - сам не понимаешь. что хочешь добиться в архитектуре. В итоге сам не понимаешь, куда движешься. У тебя НЕТ архитектуры и понимания, как сделать правильно, поэтому мечешься. А архитектура - это когда шаг влево, шаг вправо - расстрел. Это когда ты делаешь всё по оговоренным правилам и не задаешься вопросами, а как правильно.

class Advert {
  // Объявление детально
  public function displayAdvert(){
    // Показать объявление детально
  }
}


какая-то дичь. Ты должен оперировать в первую очередь контроллером, моделью, представлением. Модель - это классы сущностей и сервисы. Во многих популярных фреймворках модель - это сущность+ActiveRecord. Можно использовать паттерн модель + DataMapper. Не суть.

Вот что такое Advert? Это объявление. Это модель. У нее нет никакого метода displayAdvert. Этот метод может быть у контроллера объявлений, который выводит ОДНО объявление на странице.
Что, по твоей логике, должен делать этот метод? Чем он отличается от метода ХРАНИЛИЩЕ::findById()?

public function displayMyAdverts(){
Это должно быть в AdvertCollection::findByUser()
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы