uonick
@uonick
Сгибатель бананов

Вопрос логики: как правильно назвать метод?

Всем привет!
Смотрите, простая ситуация: юзер ставит лайк под фото/комментарием/профилем пользователя.
Какой вариант понятней и правильней с точки зрения логики кода и названия методов(не обращая внимания на техническую реализацию):
$user->likePhoto($photoId);
$user->likeProfile($profileId);
$user->likeComment($commentId);

против:
$photo->like($userId);
$profile->like($userId);
$comment->like($userId);

или
$like->set('photo', $userId);
$like->set('profile', $userId);
$like->set('comment', $userId);

или..
ваш_вариант.

(Встречал проекты со всеми видами.)
  • Вопрос задан
  • 462 просмотра
Решения вопроса 3
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
лайки штука интересная. Для начала сам по себе "лайк" это не сущность, это связь между пользователем и фотографией. Идем дальше.

Сущность юзера должна знать о лайках? Скорее всего нет. Сущность которую лайкают должна знать о лайках? По сути тоже нет, но это удобно. Потому пусть будет так.

Итого минимум который нам нужен для того что бы сделай лайки - это одностороння many-to-many связь. Если брать например Doctrine реализация будет примерно такой:

class Photo {
    /**
     * @type User[]|ArrayCollection
     */
    private $likes;

    public function __construct(/** ... */) {
        // тут какой-то еще код
        $this->likes = new ArrayCollection();
    }

    // ... другая логика

    public function like(User $user)
    {
          $this->likes->add($user);
    }
}


Итого имеем интерфейс:

$photo->like($user);

мол мы отправляем сообщение объекту $photo что он кому-то нравится, и передаем кому. А тот уже сам внутри все разрулит.

Поскольку вы захотели сделать Like сущностью, подозреваю что вы хотите знать еще дополнительную информацию вроде "когда кто-то что-то лайкнул" и т.д. Зачем - не мое дело. Но просто давайте чуть изменим имплементацию метода не меняя интерфейса:

public function like(User $user) 
{
    $this->likes->add(Like::photo($this, $user));
}


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

Еще такой интересный момент, что мы можем все методы вроде `isLikedBy` и т.д. вынести прямо в сущность при желании. Для этого в случае доктрины можно воспользоваться extra lazy ассоциациями и методом matching у коллекции которая вместо обхода объектов может и sql выполнить по критерии какой-то.

Ну и что бы совсем закончить. Пока у нас корнем агрегата сущностей (состоящего из Photo и User) корнем выступает сущность Photo. Но может статься так что лайки у нас могут быть еще сложнее. Например нам надо учитывать репосты и считать количество лайков из этого расчета (как вконтактике например). Тогда с реляционной базой мы быстро начинаем проигрывать и мы можем взять Neo4J например для того что бы хранить лайки как граф. Тогда все удобно и быстро. И тогда можно вытащить логику работы с лайками наверх так что сущности сами о ней вообще ничего не будут знать.

Но это наверное уже совсем другая история.
Ответ написан
alexey-m-ukolov
@alexey-m-ukolov Куратор тега PHP
Я бы всё это дело обернул в человекопонятный DSL: $user->likes($entity);.
А уже внутри метода likes() создаётся объект Like, в который передаётся лайкнутая сущность (ну и пользователь, разумеется) и там внутри уже разруливается конкретное поле, которое нужно заполнить. Инкапсуляция, полиморфизм, все дела.

Те же яйца, только сбоку: $entity->likedBy($user).

Если в качестве источника действия установить пользователя, то можно будет написать вдобавок $user->noLongerLikes($entity), чтобы снять лайк. При другой организации DSL получится страшненький.

P.S. Лучше оперировать целыми объектами, а не передавать туда-сюда id. Это позволит и код кое-где упростить и тайпхинты расставить.
Ответ написан
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
Человеческий стиль: (сущность, действие, объект действия)
$user->like->photo($photoId);
$user->like->profile($profileId);
$user->like->comment($commentId);
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
0neS
@0neS
$like = (new Like())->setUser($user)->setPhoto($photo);
Ответ написан
@mletov
Первый какой-то вообще странный

К третьему я бы добавил ид объекта (фото, профиля и т д ), который лайкают
$like->set('photo', $objectId, $userId);
$like->set('profile', $objectId, $userId);
$like->set('comment', $objectId, $userId);
Ответ написан
Ваш ответ на вопрос

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

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