Паттерн Фабрика реализацияя через __callStatic

Professor

Новичок
Тугай
Все супер, кроме }else{$type = "login";}, должно быть скорее }else{$type = "unknown";}
Это по умолчанию будет использоваться авторизация как по логину. Соответственно ошибка будет "Не верное сочетание логин пароль". А если указать unknown, то нужно для этого отдельную обработку делать.
 

AnrDaemon

Продвинутый новичок
Вам уже раньше задали правильный вопрос, на который вы усиленно стараетесь не отвечать - по какому принципу у вас выбирается тот или иной метод авторизации?
 

Тугай

Новичок
Professor
Можешь почитать у Метт Зандстра. PHP Объекты шаблоны и методики программирования. глава 11 шаблон Command.

Следуя книге:
$data - это контекст команды, и твой $type уже должен сидеть в $data['type'];
Остальное все так же, только if получается лишний, посколку когда клиент формирует запрос он знает type и тут его перевычислять не надо.
 

Professor

Новичок
Я не знаю типа авторизации.
Мне в этот скрипт может постучаться любой запрос со своими данными. Допустим Facebook после подтверждения личности человека редиректит его на страницу авторизации и передает токен и ID пользователя.
Где я должен определять что этот тип авторизации через Facebook? Перед вызовом класса Adapter::Auth определять тип и передавать его как параметр?

Я не хочу этого делать во всех местах, где буду использовать этот метод(авторизация конечно не самый удачный пример, так как используется обычно только в одном месте). Тем не менее, есть несколько контроллеров авторизаций. И я не хочу в каждом писать один и тот же код для определения метода авторизации. Я хочу эту логику вынести в одно место, и это Adapter::Auth
 

keltanas

marty cats
Если создание статичного хелпера, который ты выдаешь за фабрику, не самоцель, то посмотри, как Observer работает. В твоем случае этот паттерн больше подойдет.
 

keltanas

marty cats
В этом случае, имхо, объект аутентификации сам должен знать, когда он применим. А так получается, что за применимость того или иного метода аутентификации отвечает какой-то внешний объект.
Получается, что каждый раз, когда мы захотим добавить новый метод, нам придется в "фабрику" (ну или в нашем случае это действительно больше стратегия) добавлять новый алгоритм выбора. И как следствие, каждый раз, подключая новый метод, перепрограммировать весь механизм аутентификации )))
 

WMix

герр M:)ller
Партнер клуба
ну в общем да, есть одим метод аутификации,
PHP:
{new Auth()}->exec($cfg,$post);
который либо понимает как работать с почтой и использует правильный класс, либо вернет исключение
 

keltanas

marty cats
WMix
PHP:
$authManager->addMethod(new Session());
$authManager->addMethod(new Vkontakte());
$authManager->addMethod(new Facebook());
$authManager->addMethod(new LoginForm());

$result = $authManager->authenticate();

// где
class AuthManager
{
    public function authenticate()
    {
        /** @var AuthMethod $method */
        foreach ($this->methods as $method) {
            if ($method->authenticate()) {
                return $method;
            }
        }
        return false;
    }
}
 
  • Like
Реакции: AmdY

AnrDaemon

Продвинутый новичок
Мне одному кажется, что топикстартер сам себе проблемы создаёт? Я вот не представляю, как метод атентификации может вызываться без информации о том, что же мы всё таки пытаемся определить.
 

WMix

герр M:)ller
Партнер клуба
AnrDaemon
не понимаешь как работают авторизации в соц сетях, или не сообразишь, что URL вызова создан тобой, и там можно спрятать любую необходимую информацию?
 

Тугай

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

fixxxer

К.О.
Партнер клуба
Началась джава головного мозга. =)

PHP:
abstract class AuthProvider {

    public static function factory($authProviderName, array $args = []) {
         $className = 'AuthProvider' . $authProviderName;
         if (!class_exists($className)) {
             throw new \InvalidArgumentException("Unknown auth provider: '$authProviderName'");
         }
         return new $className($args);
    }

    public static function factoryByRequest(Request $Request) {
         if ($Request->has('fb_id')) {
            $providerName = 'Facebook';
         }
         ...
         return static::factory($providerName, $Request->toArray());
    }


    //...

}

class AuthProviderFacebook extends AuthProvider {
    //...
}
Подобного подхода достаточно в 99% случаев.

Подход с отдельным authManager имеет смысл, если ты пишешь какую-нибудь логинзу, где 100500 методов авторизации. Вот когда у тебя их будет столько, что factoryByRequest будет занимать более экрана кода - тогда можно и вынести. Скорее всего, этого не произойдет никогда.

Да, метод factoryByRequest "с запашком". Но запашок берется от изначально кривой архитектуры - информацию о providerName надо гонять в урле, а не устраивать угадайку. Городить же Архитектуру и Паттерны в том случае, когда сама причина возникновения задачи - вышележащий говнокод, нет никакого смысла.
 

Professor

Новичок
Вся дискуссия сводится к решению вопроса: "Нужно ли гонять providerName в урле или не нужно?"
Мне почему то кажется что не нужно. Исходя из моего взгляда на этот вопрос, я и построил такую структуру.
Вы сейчас озвучили противоположную точку зрения. И если придерживаться ее, то действительно factoryByRequest "с запашком";

Какие плюсы таскать метод авторизации в URL?
 

Professor

Новичок
Ну вот кажется =) На интуитивном уровне.
Если попробовать пофантазировать, то:
1) Придется следить по всему коду за добавлением правильного типа авторизации ко всем ссылкам на авторизацию.
Тут конечно можно сделать функцию которая будет генерировать такие ссылки исходя из надобности и сама будет подставлять тип.
2) Данный параметр может где то потеряться(Вероятность хоть и маленькая, но есть. Неправильный редирект и параметр не учтен)
3) URL становится длинней, что не гуд, если он совсем длинный с токенами facebook-а(не знаю, бывало или нет, но может же места в URL не хватить)
4) При сменен названия типа авторизации нужно будет править и имя класса и название его в функции формирования URL для авторизации

Может это все и мелкие, незначительные и надуманные примеры. Но плюсов таскать этот параметр в URL я вообще придумать не могу.
 

fixxxer

К.О.
Партнер клуба
1) Это должно быть параметром роутинга при генерации урла. Если в твоем фреймворке урлы надо генерировать вручную, выбрось этот фреймворк
2) См. п.1. При отсутствии обязательного параметра должен быть exception.
3) Глупости какие
4) См. п.1.

Плюсы:
1) Не нужна угадайка, все четко и очевидно
2) Что ты будешь делать, если внезапно появятся два сервиса, возвращающие абсолютно идентичный набор параметров?
 

Professor

Новичок
1) Это должно быть параметром роутинга при генерации урла. Если в твоем фреймворке урлы надо генерировать вручную, выбрось этот фреймворк
Имелась ввиду ссылка на Facebook, Контакт, после перехода по которой эти соц сети будут редиректить пользователя на страницу авторизации.

2) Что ты будешь делать, если внезапно появятся два сервиса, возвращающие абсолютно идентичный набор параметров?
Вот, вот это хороший вопрос =)
 

keltanas

marty cats
Началась джава головного мозга. =)
Это ты про Observer? Так посмотри, где были Observer и Java в 1995 году? ;)
Сам-то состряпал какую-то какашку, которая должна знать все о всех методах аутентификации. )) А она о них должна знать только то, что они есть и приоритет их вызова.
А где каждый из них применим, они сами решат. Если у фейсбука в определенный момент поменяются параметры, достаточно будет отредактировать только AuthProviderFacebook. И не недо будет трогать никакие стратегии.
Реквест в них тоже можно передать, никто не против. Это уже от конкретного фреймворка зависит. Может у него там и нет вообще никакого реквеста кроме $_REQUEST ))
 

fixxxer

К.О.
Партнер клуба
Я там объяснил, из каких соображений там какашка. Потому что сам такой подход - какашка. :)

Если где-то используется неверный архитектурный подход, не надо его маскировать паттернами. Пусть торчит и напоминает о том, где на самом деле нужен рефакторинг.

Если изначально неверный подход выбрасываем, достаточно оставить метод factory. ;)
 
Сверху