Совет по проектированию класса?

Хочу написать класс по работе с балансом пользователя, метода, очевидно только 2: снять, пополнить. Вопроса 2:

1. Можно просто реализовать обычным классом а можно создать интерфейс, в нём прописать эти 2 метода, таким образом, класс обязан будет их реализовать, таким обзом я получу гарантию что в этом классе они реализованы. И всё интерфейс в этом случае не принесёт других бонусов? Чё-то как-то слишком просто ))

2. После пополнения баланса в некоторых случаях у юзера надо сдвинуть дату до которой разрешено использование определённой услуги. Я правильно понимаю, что эту функцию стоит реализовать в другом классе, т.к. это другой функционал, другая таблица БД, другой тип данных (дата а не деньги)
  • Вопрос задан
  • 232 просмотра
Решения вопроса 4
qonand
@qonand
Software Engineer
1. Интерфейс приносить много бонусов с точки зрения архитектуры. Изучите контрактное программирование - поймете все преймущества
2. Да Вы правильно понимаете...
Ответ написан
Комментировать
BoShurik
@BoShurik
Symfony developer
Дополню ответ Максим Федоров
К примеру. если понадобится кешировать данные баланса и логировать его изменение. С использованием интерфейсов будет все очень просто и лаконично:
Код
interface BalanceInterface
{
    public function get();

    public function inc($value);

    public function dec($value);
}

class Balance implements BalanceInterface
{
    private $value;

    public function get()
    {
        return $this->value;
    }

    public function inc($value)
    {
        $this->value += $value;
    }

    public function dec($value)
    {
        $this->value -= $value;
    }
}

class CacheBalance implements BalanceInterface
{
    /**
     * @var BalanceInterface
     */
    private $next;

    /**
     * @var \Psr\Cache\CacheItemPoolInterface
     */
    private $cache;

    public function __construct(BalanceInterface $next, \Psr\Cache\CacheItemPoolInterface $cache)
    {
        $this->next = $next;
        $this->cache = $cache;
    }

    public function get()
    {
        $item = $this->cache->getItem('balance');
        if ($item->isHit()) {
            return $item->get();
        }

        $value = $this->next->get();

        $item->set($value);
        $this->cache->save($item);

        return $value;
    }

    public function inc($value)
    {
        return $this->next->inc($value);
    }

    public function dec($value)
    {
        return $this->next->dec($value);
    }
}

class LogBalance implements BalanceInterface
{
    /**
     * @var BalanceInterface
     */
    private $next;
    /**
     * @var \Psr\Log\LoggerInterface
     */
    private $logger;

    public function __construct(BalanceInterface $next, \Psr\Log\LoggerInterface $logger)
    {
        $this->next = $next;
        $this->logger = $logger;
    }

    public function get()
    {
        return $this->next->get();
    }

    public function inc($value)
    {
        $this->logger->info(sprintf('Increase balance by %d', $value));

        return $this->next->inc($value);
    }

    public function dec($value)
    {
        $this->logger->info(sprintf('Decrease balance by %d', $value));

        return $this->next->dec($value);
    }
}

$initialBalance = new \Balance();
$cacheBalance = new \CacheBalance($initialBalance, $cache);
$logBalance = new \LogBalance($cacheBalance, $logger);

$balance = $logBalance;


https://ru.wikipedia.org/wiki/Декоратор_(шаблон_пр...
Ответ написан
@egormmm
Борітеся — поборете!
1. Интерфейс определяет что должен делать компонент реализующий его. Другими словами - это правила. А класс - это обьект, который его реализует, т.е. каким-то конкретными образом выполняет его.
Используя интерфейс вместо конкретного класса в аргументах метода вы тем самым оставляете возможность использовать другой класс в этом методе без изменения кода этого метода.
Если не понимаете зачем нужен интерфейс - не парьтесь, используйте класс в методе.
Ответ написан
Комментировать
pazukdev
@pazukdev
Java Dev
По п. 1 Вашего вопроса.
Если уверены, что через этот функционал (эту сущность) не будет проходить ось изменений, то пишите класс. Если нет - интерфейс. Или абстрактный класс, если эта сущность должна обладать каким-то state.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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