All streams
Search
Write a publication
Pull to refresh
49
-0.1
Alex Gusev @flancer

Я кодирую, потому что я кодирую…

Send message

Если бы можно было ставить ссылку на структуру в док-блоке, хватило бы примерно такого:


/**
 * ..
 *
 * @param {Object} opts
 * @param {string} opts.currency
 * @param {Object} opts.screen - see @Screen.obj
 * @param {Object} opts.suite - see @Suite.obj
 */
function doGood(opts) {}
Судя по примеру на JS — вас не волнует, что там реально предается в opts

Не совсем так. Я бы с радостью задал ожидаемую структуру входного объекта и для JS, вот только пока не знаю, как это сделать. Лучшее, что я пока нашел:


/**
 * ..
 *
 * @param {Object} opts
 * @param {string} opts.currency
 * @param {Object} opts.screen
 * @param {boolean} opts.screen.save
 * @param {string} opts.screen.prefix
 * @param {Object} opts.suite
 * @param {string} opts.suite.pack
 * @param {string} opts.suite.scenario
 */
function doGood(opts) {
    var opts = opts || {}
    var suite = opts.suite || {pack: "undef", scenario: "undef"}
    var optsScreen = opts.screen || {} // screenshots related opts
    var saveScreens = optsScreen.save || false // don't save screenshots by
    var savePrefix = optsScreen.prefix || "default" // default prefix for screenshots
    var currency = opts.currency || "EUR"
]1

Получается "масляное масло" — задавать структуру входного аргумента в док-блоке и парсить его же в теле функции в первых строках. Структура входных аргументов на PHP удобна всплывающими подсказками и autocomplet'ом (поддержка IDE).

Виной всему — моя лень. Мне было лениво расписывать "нездоровый" вариант на десять аргументов, и я остановился на более коротком, надеясь, что идея будет понятной. В результате запорол пример. Ну что ж, буду работать над собой.

У вас тоже? Вы с коллегой lair'ом там что, на скорость чтения соревнуетесь? В таком случае примите от меня респекты и в свой адрес, коллега.

Поражаюсь вашей скорости чтения, коллега.

Да, так и есть. Если очень сильно применять SRP, то начинают попадаться классы, мокать которые при тестировании — полная ерунда. Коллега Dimitar Ginev как раз и рекомендует не заниматься ерундой и не тестировать подобные классы (orchestrators).

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

А после резюме — опрос. Весь текст перед — это вводная, раскрывающая пункты опроса. Очевидно, это не для всех очевидно, но я сделал все, что мог.

Я пытаюсь выяснить является ли тезис "Пока же создание очередного web-приложения зачастую начинается с проектирования собственной структуры данных для аутентификации пользователей" заблуждением или нет.


Это же очевидно, разве нет?

Потому что статья про web-приложения. И если приглядываться внимательнее, то на картинке — персонажи из компьютерной игры Far Cry (компьютерная графика бросается в глаза даже тем, кто в принципе не знает, что такое компьтерная графика). Зачем вы с коллегой kk86 в статье про web-приложения с КДПВ из компьютерной игры начали обсуждать необходимость интеллекта в охоте на мамонтов — это вопрос из раздела "загадочные тайны безграничной Вселенной". Ну, коллега, допустим, блеснул знанием английского. А чем блеснули вы?

Спасибо, коллега! Приятно видеть, что в PHP-среде есть подвижки в этом направлении. Вытащил в том или ином виде структуры данных для каждого из модулей:


yii2-user:


/**
 * User ActiveRecord model.
 *
 * @property bool    $isAdmin
 * @property bool    $isBlocked
 * @property bool    $isConfirmed
 *
 * Database fields:
 * @property integer $id
 * @property string  $username
 * @property string  $email
 * @property string  $unconfirmed_email
 * @property string  $password_hash
 * @property string  $auth_key
 * @property string  $registration_ip
 * @property integer $confirmed_at
 * @property integer $blocked_at
 * @property integer $created_at
 * @property integer $updated_at
 * @property integer $last_login
 * @property integer $flags
 *
 * Defined relations:
 * @property Account[] $accounts
 * @property Profile   $profile
 *
 * Dependencies:
 * @property-read Finder $finder
 * @property-read Module $module
 * @property-read Mailer $mailer
 *
 * @author Dmitry Erofeev <dmeroff@gmail.com>
 */

FOSUserBundle:


    /** @var mixed */
    protected $id;
    /** @var string */
    protected $username;
    /** @var string */
    protected $usernameCanonical;
    /** @var string */
    protected $email;
    /** @var string */
    protected $emailCanonical;
    /** @var bool */
    protected $enabled;
    /** @var string The salt to use for hashing. */
    protected $salt;
    /** @var string Encrypted password. Must be persisted.*/
    protected $password;
    /** @var string Plain password. Used for model validation. Must not be persisted. */
    protected $plainPassword;
    /** @var \DateTime */
    protected $lastLogin;
    /** @var string Random string sent to the user email address in order to verify it.*/
    protected $confirmationToken;
    /** @var \DateTime */
    protected $passwordRequestedAt;
    /** @var Collection */
    protected $groups;
    /** @var array */
    protected $roles;

Laravel:


        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password', 60);
            $table->rememberToken();
            $table->timestamps();
        });

ZfcUser:


    CREATE TABLE user
    (
        user_id       INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
        username      VARCHAR(255) DEFAULT NULL UNIQUE,
        email         VARCHAR(255) DEFAULT NULL UNIQUE,
        display_name  VARCHAR(50) DEFAULT NULL,
        password      VARCHAR(128) NOT NULL,
        state         SMALLINT
    ) ENGINE=InnoDB;

По ним можно видеть, какую функциональность в дополнение к аутентификации (не)предлагает соотв. модуль для соотв. фреймворка. Вполне возможно с одним фреймворком можно (будет) использовать разные модули с различными схемами данных, обеспечивающими различный функцонал (базовый, расширенный, специализированный). И вполне возможно, различные модули для различных фреймворков будут имплементировать одинаковые структуры данных. И вполне возможно, что эти структуры данных будут одинаковы не только для различных модулей различных PHP-фреймворков, но и для аналогичных модулей Java/C#/Python/… фреймворков.


Какая разница, на чем написан server side, если он работает с MySQL/Postrgres/MongoDB/Oracle/… и решает одни и те же задачи (authentication, password management, etc.)? Структуры данных должны соответствовать решаемым задачам, а не тому языку, на котором происходит обработка этих данных.

Что статья про web-приложения, а не про кроманьонцев.

Если вы хотите что-то узнать — задайте вопрос. В ваших комментах нет ни одного вопроса.

Спасибо за дополнения, коллега Vlad_fox.


Я, возможно не очень явно, тему тестирования затрагивал в "Там на неведомых дорожках...". TDD входит в конфликт с первыми двумя пунктами — приспосабливаемость (раз уж "адаптивность" устойчиво ассоциируется с версткой) и неопределенность. Поэтому у меня к нему очень настороженное отношение. Безусловно полезная вещь при наличии ресурсов и ясного представления о предмете разработки. При недостатке ресурсов или отсутствии ясного понимания что и как делать TDD становится обузой или тормозом. Но тестирование в том или ином виде (и лучше автоматическом) быть обязано — иначе "асфальт не натоптать" (если только толпы пользователей не запустить).


Необходимость использования готовых фреймворков и библиотек я пытался отразить в пунктах "Модульность" и "Муравейник". Тоже, наверное, достаточно неявно. Пока что мы даже на уровне данных еще не имеем каких-либо стандартов для даже таких древних "велосипедов", как аутентификация. Хотя, казалось бы, почему бы не выработать одну-две-три схемы для подобной структуры? Сколько я различных названий видел для первого поля аутентификационной формы — login, user, username, email. Можно ведь описать в XSD типовые структуры данных (одно- и двух-факторная аутентификация, с уникальным email'ом у пользователя или группой email'ов, с физическим представителем юридческого лица и т.д.) и преобразовывать структуру в SQL/NoSQL/Files/InMemory/… В Java подобные попытки делались. Я понимаю, что зафункционалить все стандартно на различных языках программирования невозможно, но на уровне структур данных можно найти консенсус, разве нет? Хотя наверно, проще написать свой "велосипед" на тему аутентификации, чем всем вместе договориться использовать единую схему данных.

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

Было бы любопытно сравнить предлагаемые структуры данных, обеспечивающие аутентификацию, допустим, в Asp.Net MVC и в cookiecutter.

Отсутствие у кроманьонцев развитой транспортной системы как бы тоже намекает, что с плохой дыхалкой мамонта не догнать, а без развитой мускулатуры разобранную тушку к месту поедания не переместить. Хотя я и допускаю, что особо высокоинтеллектуальные кроманьонцы вполне могли создавать ситуации, когда мамонты добровольно приходили на порог их жилищ и самоубивались, дабы совершенно исключить применение грубой физической силы со стороны древнейшей интеллигенции. Остальным же, не столь интеллектуальным, приходилось убалтывать последних неандертальцев понапрягаться физически вместо себя. Возможно от этого, кстати, неандертальцы и вымерли — от перенапряжения. Когда-нибудь британские ученые осветят и этот вопрос.

Я надеюсь, мы все-таки говорим за аутентификацию — она несколько до проблемы авторизации стоит. Сначала мы узнаем, с кем имеем дело, а у же потом — какие у него права доступа и к чему.


Cookiecutter Django is a framework for jumpstarting production-ready Django projects quickly

Допускаю, что cookiecutter прекрасно решает эту проблему для Django-проектов. Это как Ruby on Rails, только Django. А если ваш заказчик настаивает, чтобы backend вашего web-приложения был написан на PHP/Java/C#/JavaScript/… — какие фреймворки с готовой аутентификацией вы мне посоветуете? Или, допустим, ваш заказчик хочет иметь в своем web-приложении двухфакторную аутентификацию (через SMS — самый распространенный вариант)? Это ведь тоже уже достаточно "велосипед" — кукикаттер имеет решение этой проблемы хотя бы для Django-проектов?

Говорят, эту проблему решают фреймворки. Или нет? :)
нет :(

Information

Rating
Does not participate
Location
Рига, Латвия, Латвия
Date of birth
Registered
Activity

Specialization

Fullstack Developer
Lead
From 3,000 €
JavaScript
HTML
CSS
Node.js
Vue.js
Web development
Progressive Web Apps
PostgreSQL
MySQL
GitHub