Skip to content

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

Notifications You must be signed in to change notification settings

PankovAlxndr/ip-geo-locator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

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-адресу. Учебный проект по применению паттерна Декоратор.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages