Шаблон фабрика, как способ разделения прав пользователей

В проектах, где требуется разделить права пользователей по ролям, можно использовать шаблон проектирования фабрика (fabric). Данная статья поможет разобраться каким именно образом.

Допустим есть простой URI роутер:

$path=dirname(__FILE__);
require_once($path . '/lib/router/routeurl.php');
require_once($path . '/lib/PageError.php');
 
$routeurl = new routeURL(); //Создаем объект роутера
$routeurl->enableFabric();  //Указываем использовать фабричный паттерн
 
try {
    $routeurl->launch();
    } catch ( badClassNameException $e ) {
        PageError::show('400', $e->getMessage());
    } catch ( classFileNotFoundException $e ) {
        PageError::show('401', $e->getMessage());
    } catch ( classNameNotFoundException $e ) {
        PageError::show('402', $e->getMessage());
    } catch ( classMethodNotFoundException $e ) {
        PageError::show('403', $e->getMessage());
    }

В index файле инициализируем следующим образом:

class News extends Core
{
    public function show()
    {
        //Какой-то код, для определенной группы пользователей, назовем ее Foo.
    }
}
 
class Allnews extends News
{
    public function show()
    {
        //А этот код, для другой группы пользователей - Bar.
    }
 
    public function add()
    {
       //Какой-то еще метод, для группы Bar.
    }
 
}
 
class Fabric
{
    public static function getInstance()
    {
        if($_SESSION['allowadvanced']===true)
            return new Allnews;
        else
            return new News;
    }
}

Рассмотрим сначала поведение роутера при отключенном шаблоне фабрика. Если посетитель набирает в адресной строке браузера, например, example.com/news/show, то в директории с контроллерами ищется файл news.php, в котором находится одноименный класс. Создает его объект и вызывает метод show.

Ситуация резко меняется при включении фабрики. Роутер как и прежде ищет файл news.php, но вместо того, чтобы создать объект, вызывает статический метод класса fabric, который возвращает нужный объект. Пример контроллера:

class News extends Core
{
    public function show()
    {
        //Какой-то код, для определенной группы пользователей, назовем ее Foo.
    }
}
 
class Allnews extends News
{
    public function show()
    {
        //А этот код, для другой группы пользователей - Bar.
    }
 
    public function add()
    {
       //Какой-то еще метод, для группы Bar.
    }
 
}
 
class Fabric
{
    public static function getInstance()
    {
        if($_SESSION['allowadvanced']===true)
            return new Allnews;
        else
            return new News;
    }
}

Таким образом, пользователь, у которого недостаточно прав не только не получит доступ к определенным методам. Более того — даже не узнает об их существовании!