PankovAlxndr / ip-geo-locator

Определение местоположения по ip-адресу. Учебный проект по применению паттерна Декоратор.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Учебный проект для понимания паттернов Декоратор\Заместитель

Build Status Code Coverage Code Intelligence Status Scrutinizer Code Quality

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

Было реализовано

  • Покрытие тестами - 100%
  • Декоратор, позволяющий указать несколько разных реализаций локатора (метода определения местоположения по ip) .
  • Заместитель, позволяющий кешировать результаты и, в некоторых случаях, вовсе не вызывать метод служебного класса.
  • Декоратор, позволяющий записать ошибку в лог и продолжить работу.

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

Примеры использования example.php

<?php

declare(strict_types=1);

use IpGeoLocator\CacheLocator;
use IpGeoLocator\ChainLocator;
use IpGeoLocator\Ip;
use IpGeoLocator\MuteLocator;
use IpGeoLocator\PsrLogErrorHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Psr16Cache;

require_once '../vendor/autoload.php';
require_once 'DaDataLocator.php';

/*
 * Клиент реализует свой локатор, в данном случае через сервис dadata.ru.
 * Причем у данного "локатора" могут быть свои какие угодно зависимости, главное реализовать интерфейс (контракт)
 *
 * В данном случае мы декорируем вызов "нашего" DaDataLocator'а несколькими другими "локаторами"
 * ChainLocator -> CacheLocator -> MuteLocator -> DaDataLocator
 *
 * Chain локатор в данном примере избыточен, тк у нас всего один DaDataLocator,
 * такая конфигурация в качестве примера.
 *
 * */

$errorHandler = new PsrLogErrorHandler(new Logger('basic', [new StreamHandler('var/ip-geo-locator.log')]));
$cache = new Psr16Cache(new FilesystemAdapter('cache-locator', 3600, 'var'));

$daDataLocator = new DaDataLocator('...');
$muteLocator = new MuteLocator($daDataLocator, $errorHandler);
$cacheLocator = new CacheLocator($muteLocator, $cache);
$chainLocator = new ChainLocator($cacheLocator);

$location = $chainLocator->locate(new Ip('46.229.184.75'));
var_dump($location);

/*
 * Ответ
 *
 * class IpGeoLocator\Location#30 (3) {
 *   private string $country =>
 *   string(12) "Россия"
 *   private ?string $region =>
 *   string(22) "Ярославская"
 *   private ?string $city =>
 *   string(18) "Ярославль"
 * }
*/

Тесты

Запуск тестов:

composer test

About

Определение местоположения по ip-адресу. Учебный проект по применению паттерна Декоратор.


Languages

Language:PHP 100.0%