Статьи

Изучите аспектно-ориентированное программирование с CodeIgniter, часть 1

Вы когда-нибудь слышали об аспектно-ориентированном программировании (AOP) раньше? Это широко используемая концепция при разработке систем корпоративного уровня, хотя она не получила большого применения в PHP. Я собираюсь использовать эту статью как возможность познакомить PHP разработчиков с AOP.

Этот урок будет доставлен вам в виде серии из трех частей. В этой части я объясню концепции АОП. Во второй части я покажу вам практическое использование AOP и создание структуры правил AOP. Наконец, я покажу вам, как интегрировать функциональность AOP с использованием CodeIgniter в части 3.

Что такое АОП?

При разработке приложений мы часто находим требуемые функциональные возможности, которые должны использоваться в нескольких частях нашего кода, но которые на самом деле не связаны с бизнес-логикой. Хорошим примером является проверка подлинности, чтобы убедиться, что пользователь вошел в систему перед выполнением определенной задачи. Такие задачи называются сквозными задачами. Давайте посмотрим на определение сквозных проблем, данное в Википедии :

В информатике сквозные проблемы — это аспекты программы, которые затрагивают другие проблемы. Эти проблемы часто невозможно четко разложить на остальную часть системы как при проектировании, так и при реализации, и могут привести к разбросу (дублирование кода), запутыванию (значительные зависимости между системами) или к тому и другому.

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

Рассмотрим ситуацию, когда вы являетесь редактором блога, такого как SitePoint. Вам необходимо войти в систему, чтобы создавать сообщения, утверждать сообщения, редактировать сообщения и т. Д. Если вы не вошли в систему, вы должны быть перенаправлены на экран входа в систему. Чтобы обеспечить такое поведение, код должен проверять подлинность перед каждой из задач, упомянутых выше.

<?php
class BlogPost extends CI_Controller
{
    public function createPost() {
        if (!Authentication::checkAuthentication()) {
            // redirect to login
        }
        else {
            // proceed
            Messages::notifyAdmin();
        }
    }

    public function approvePost() {
        if (!Authentication::checkAuthentication()) {
            // redirect to login
        }
        else {
            // proceed
        }
    }

    public function editPost() {
        if (!Authentication::checkAuthentication()) {
            // redirect to login
        }
        else {
            // proceed
        }
    }

    public function viewPost() {
        // ...
    }
}

Посмотрите на приведенный выше код, и вы увидите, что checkAuthentication()notifyAdmin() Это не только дублированный код, но и класс BlogPost Аутентификация и уведомления должны быть сделаны отдельно. Мы нарушили принцип единой ответственности :

Принцип единой ответственности гласит, что каждый класс должен нести одну ответственность, и эта ответственность должна быть полностью заключена в класс. Все его услуги должны быть тесно связаны с этой ответственностью.

Итак, теперь мы пришли к месту, где мы можем понять значение АОП. Межотраслевые задачи могут быть сгруппированы в объекты, называемые «аспектами», а процесс отделения сквозных задач от нашего основного кода называется Аспектно-ориентированным программированием.

АОП Терминология

Есть несколько конкретных терминов, используемых в АОП для объяснения его особенностей. Понимание этих терминов, вероятно, станет ключом к успешной интеграции AOP в ваши проекты PHP.

  • аспект
  • Совет
  • Joinpoint
  • Pointcut

Мы только что узнали, что такое аспект, поэтому теперь давайте посмотрим, что означают остальные три термина.

Совет

Функциональность аспекта называется советом. Как следует из названия, советы определяют, что делать в определенных ситуациях и когда это делать. В нашем предыдущем примере проверка аутентификации (что) — это совет, и его следует применять перед выполнением кода (когда) внутри определенных методов.

Joinpoint

Точки соединения — это места в приложении, где мы можем создавать советы. Оглядываясь назад на пример кода, вы можете найти несколько мест, где я назвал функциональность, которая не имеет прямого отношения к бизнес-логике. Например, в createPost() Это обе возможные точки соединения.

Соединительные точки могут быть определены в любом месте кода вашего приложения, но применение советов будет доступно только в определенных точках в соответствии с вашими особенностями инфраструктуры AOP и будет обсуждаться позже в этом руководстве.

Pointcut

Pointcut определяет способ сопоставления советов с определенными точками соединения. Хотя в нашем примере у нас есть пара точек соединения, в вашем приложении могут быть тысячи точек соединения, и вам может не потребоваться применять рекомендации ко всем из них. В таких ситуациях мы можем сопоставить подмножество точек соединения, которое называется указателями, и применять рекомендации только к выбранным элементам.

Предположим, что мы хотим посоветовать createPost()approvePost()editPost()viewPost() Мы должны как-то подобрать эти 3 метода и применить советы. Позже мы будем создавать XML-файл с подробностями аспектов, который будет содержать регулярные выражения для сопоставления точек соединения.

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

Типы рекомендаций АОП

Есть несколько способов, которыми мы можем посоветовать наш код. Как я упоминал ранее, доступность этих типов рекомендаций зависит от типа используемой платформы AOP, но некоторые типы, с которыми вам следует ознакомиться:

  • Перед советом
  • После возвращения совета
  • После броска совета
  • Вокруг совета

Перед советом

Перед тем, как совет будет применен перед определенной точкой в ​​вашем коде, обычно вызовом метода.

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

 <?php
class PathController
{
    function controlPaths($className, $funcName) {
        Authentication::checkAuthentication();
        $classObj = new $className();
        $classObj->$funcName();
    }
}

Здесь я создал фиктивный класс, чтобы показать вам, как это происходит на самом деле. Предположим, что метод controlPaths() В приведенном выше коде мы применили рекомендацию checkAuthentication() Это называется перед советом.

После возвращения

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

 <?php
class PathController
{
    function controlPaths($className, $funcName) {
        $classObj = new $className();
        $classObj->$funcName();
        Database::closeConnection();
    }
}

Смотрите здесь, что после завершения метода мы очищаем ресурсы базы данных. Это называется после возвращения совета.

После броска

Если функция выбрасывает исключение в процессе выполнения, может быть применен совет После выбрасывания. Здесь, после броска совет — сообщение об ошибке.

 <?php
class PathController
{
    function controlPaths($className, $funcName) {
        try {
            $classObj = new $className();
            $classObj->$funcName();
        }
        catch (Exception $e) {
            Error::reportError();
        }
    }
}

Вокруг Советов

Четвертый тип совета — это совет, который представляет собой комбинацию как до, так и после возвращения совета.

 <?php
class PathController
{
    function controlPaths($className, $funcName) {
        Logger::startLog();
        $classObj = new $className();
        $classObj->$funcName();
        Logger::endLog();
    }
}

Резюме

В этой статье я познакомил вас с AOP. Вы должны иметь общее представление о том, чего пытается достичь АОП, и быть знакомыми с некоторыми основными терминами АОП. В следующей части этой серии я покажу вам, где требуется AOP в реальных проектах и ​​как мы можем использовать хуки CodeIgniter для создания функциональности AOP. Будьте на связи!

Изображение через Fotolia