• UML-модель Yii2-приложения, реализация интерфейса группой классов. Как? Есть ли под это паттерн?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Нужен спец по ООП и UML, который работал в своё время с MVC!


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

    В любом случае в Yii такие подходы работают очень плохо. Там вы не ООП делаете а базу данных проектируете (это чуть разные вещи), и все остальное уже от этого отталкивается.

    Если вы хотите по UML фигачить (не понятно зачем правда, но это уже ваше дело), то имеет смысл брать какую ORM заточенную под ОО-first (по сути Doctrine2 из ныне существующих) и там уже развлекаться. Там профит будет.

    p.s. забудьте об этой бесполезной для бэкэнда аббревиатуре MVC. Пока вы "проектируете контроллеры" - толку от него нет (ну то есть пока у вас логика работы с данными в контроллере).

    Читаю GOF, Зандстру и т.п.


    Почитайте Applying UML and Patterns - Craig Larman - замечательная книга. Еще дядю боба можете почитать (про SOLID). Если вас интересуют темы проектирования то это будет полезно. Еще раз уж заговорили о проектировании логики предметной области - Эрик Эванса - Предметно ориентированное проектирование.

    Задача 1


    1) композиция всегда лучше наследования
    2) наследование нужно для того что бы организовать подтипы. Если у вас есть сущности которые по своей природе требуют наследование - то можно. А так - лучше его избегать. ООП как бы не про наследование вообще.
    3) интерфейсы нужны для того что бы организовать инверсию зависимости и/или полиморфизм подтипов. У Лармана можете почитать про protected variations для того что бы понять зачем их юзать.

    Задача 2


    В UML отношения между типами очень легко и просто отображаются:

    bell_fig10.gif
    - Base[classname] - wrappers для обеспечения ровного обновления самого Yii в дальнейшем, не обращайте внимания.


    Как это не обращать внимания если вы делаете UML ради UML? Пока я не увидел ничего от ООП на вашей диаграмке. Есть структуры данных с публичными пропертями, есть... контроллеры (внезапно) которые мутируют состояние этих структур.... Это не ООП - это процедурное программирование с классами.

    для такой простой задачи я пилю UML исключительно в целях тренинга


    Пока это выглядит как впустую потраченное время, поскольку вы выбрали не лучший инструмент (yii) что бы тренироваться проектировать ОО решения.

    Я рекомендовал бы вам:

    - Разобраться что такое ООП на самом деле (это не про инкапсуляцию. полиморфизм и уже тем более не про наследование ибо все это было еще до ООП и все это кроме наследования является важными принципами структурного программирования). Это про сокрытие состояния и управление зависимостями (связанность, coupling & coheasion у Лармана)
    - Взять более подходящие для проектирования ОО решений инструменты (какой-нибудь модный нынче Laravel + Doctrine2)
    - если хотите продолжать баловатся с Yii сделайте так, что бы логика предметной области ничегошеньки не знала о Yii, тогда вообще не нужно будет заниматься этими Base* классами. Почитайте про Row Data Gateway (это по сути предшевственник ActiveRecord) а именно как оно использовалось в контексте модели предметной области.

    Есть ли под это паттерн?


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

    Оригинальная книга по GoF в этом плане так себе, сейчас лучше смотреть в сторону Head First Design Patterns Ну и помимо паттернов нужно разобраться с общими принципами такими как закон деметры, SOLID, GRASP и т.д. Тогда понимание всего будет более системным.
    Ответ написан
  • Как стать Middle после Junior и Senior после Middle?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Сколько нужно мне проработать в организации чтобы стать Middle если сейчас я Junior?


    я видел людей которые за 5 лет в "организации" настолько остановились в развитии что как были джунами так и оставались.

    Джуниор - решает стандартные задачи без вопросов с незначительными рисками.
    Мидл - решает нестандартные задачи с высокими рисками. Стандартные делает быстрее и с меньшим количеством багов.
    Синьер - решает нестандартные задачи с незначительными рисками то есть меньшим количеством багов. Могут менеджить людей или проекты с технической точки зрения.

    Вот и прикидывайте.
    Ответ написан
  • Как добавить метод к классу если переопределить класс нельзя?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    завернуть работу с этими сервисами в еще один сервис который собственно будет выступать фасадом и скрывать всю грязь что вы делаете что бы было удобно.
    Ответ написан
  • Зачем в Angular есть Jsonp?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    1) Jsonp был с самых ранних версий angular
    2) angular на момент выхода версии 1.0 имел поддержку ie8 как минимум
    3) поскольку angular 1.x не может иметь значительных нарушений обратной совместимости - нельзя просто так удалять jsonp.
    Ответ написан
  • Как использовать Принцип подстановки Барбары Лисков применительно к PHP?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    В PHP отсутствует Double Dispatching и перегрузка методов


    Double Dispatch в PHP:

    class Foo {
        // ...
        public function makeSomeStuff(Bar $bar)
        {
             $bar->doStuff($this->someData); // double dispatch!
        }
    }


    Перегрузка методов:

    class Foo {
        public function foo() {}
    }
    
    class Bar extends Foo {
        public function foo() {} // перегружен!
    }


    и в ответ на отличающуюся от базового класса/интерфейса сигнатуру он вывалится с ошибкой


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

    Но решить проблему как-то нужно


    Перегрузка методов в наследниках с изменением сигнатуры это как раз таки нарушение принципа подстановки барбары лисков (LSP для сокращения).

    > Сервисы должны имплементировать какие-то общие методы, но помимо этого у них есть и специфичные методы.

    выносите "общие методы" в отдельный сервис и шарьте его как зависимость. Тогда у всех сервисов будут только специфичные методы и тогда будет достигаться принцип единой ответственности (который характеризуется как "у каждого объекта должна быть только одна причина для возможных изменений").

    p.s. венгерская нотация - это ужас. Все эти префиксы и суффиксы которые показывают кто есть тип (интерфейс, абстрактный класс) это вещи которые ломают всю красоту идеи полиморфизма и абстракции. Если хотите можем об этом пообщаться отдельно.

    Однако каждый из хендлеров может не работать с конкретной реализацией сервиса.


    Значит полиморфизм в нашем случае пошел погулять. Есть куча решений данной проблемы, в частности Chain of responsibility.

    > Visitor. Предполагает наличие в каждом из хендлеров методов типа handleService1(Service1 $service) и handleService2(Service2 $service), при этом один из методов остается пустым

    зачем так усложнять то? У вас должен быть снаружи только один публичный метод а внутри уже реализация сама разберется. Ну то есть если хотите - можете внутри сделать два приватных метода но это так же странно.

    > Массив маппинга, который говорит, какой хендлер может обрабатывать какой из сервисов.

    Опять же излишнее усложнение.

    Короче ваша проблема в том что у вас есть некие сервисы, с неким интерфейсом, которые по факту делают совсем разные вещи. То есть они априори не могут принадлежать к одному и тому же типу. Ну и нарушение LSP на лицо, вы не можете в коде заменить одну реализацию сервиса другой.

    Дальнейшие варианты возможны только после того, как вы опишите на высоком уровне что вам нужно сделать. Ну то есть не то к чему вы пришли а почему вы к этому пришли и какая задача стояла изначально.
    Ответ написан
  • Как правильно написать unit тест?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    1) это не юнит тест, это интеграционный тест. Он проверят "часть системы в сборе", в вашем случае апишку. Если бы вы тестировали через UI (то есть через ангуляр) - это называлось бы end-to-end тест (от кнопок до базы данных мол).

    2)
    На просторах инета вижу простые примеры тестов которые проверяют на true false


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

    Что вам по сути важно когда вы пишите апишку? Скорее всего вы хотите всегда знать что структура ваших ответов не сломалась. Что вы случайно не поменяли имя поля, или случайно не убрали нужные поля. Для этого есть такая штука как json schema. То есть мы берем json и проверяем на соответствие. Опять же для phpunit можно найти готовые ассерты что бы не пилить велосипед.

    Далее, что еще нам может хотеться проверить - статус коды. Это опять же легко и думаю в документации к laravel это есть. Так же возможно вы захотите проверять заголовки но это уже специфичные штуки.

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

    Ну и возможно вам захочется проверить данные в json ответе. Тут уже есть кучи вариантов. Я например запилил свой велосипед для частичного сравнения JSON-а (ну не интересно мне все проверять). Можно и другими решениями это делать, но лично я такие штуки на этом уровне проверяю крайне редко, ибо... ну у меня другие тесты за проверку логики отвечают.
    Ответ написан
  • Как выполнить Js код в многопоточном приложении delphi?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    idhttp это не браузер, он не умеет выполнять javascript.
    Ответ написан
  • Должен ли программист знать ассемблер?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    1) Сам ассемблер знать не нужно
    2) нужно знать что ассемблер вообще есть и полезно хотя бы минимально представлять как оно там внутри все работает и что есть семантический разрыв. Ну то есть не сам ассемблер даже важен, а принципы как оно что там выполняется, что есть конвееризация и т.д. Кэш процессора, зачем он нужен и т.д.
    3) это не must have, это скорее факультативные штуки
    4) это нужно для тех кто занимается разработкой систем, для которых критична производительность (так или иначе при оптимизации приходится ковыряться в опкодах/байткоде/разбираться что там делают оптимизирующие компиляторы).
    5) это нужно для тех кто разрабатывает средства для дебага и профилирования.

    Первые пару лет этого всего можно и не знать. А далее уже задачи сами определят, потом хотя бы поверхносные знания приобрести стоит просто для того что бы быть более грамотным разработчиком.
    Ответ написан
  • Можно ли использовать as в temlate?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    есть ng-init но думаю что вам нужно что-то другое. Я обычно делаю такие элиасы на уровне контроллеров компонентов. Ну и в целом ваше желание больше похоже на то, что у вас есть кусок шаблона, который выгоднее было бы выделить в отдельный компонент.
    Ответ написан
  • Как вылить проект на node.js в сеть?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Для упрощения жизни по началу можете взять какой heroku, оно относительно дешево и ничего не нужно самому настраивать. Да и инструкции для новичков есть, и free аккаунт для эксперементов.

    > вряд ли такие гиганты как yahoo и linkedin пользуются vps.

    у них свои датацентры, им проще. Но в целом от VPS процесс не сильно отличается (разве что масштабы другие). Есть еще нюансы связанные с администрированием, есть docker, есть ansible и прочее для оркестрацией серверами и т.д. Но это все потом. Не нужно стихийно пытаться покрыть сразу все. Возьмите пока вариант попроще и попробуйте а потом уже когда будет легко - можно повышать уровень и пытаться сделать так же самому на своем VPS, разбираться вообще во всем этом и т.д. Сейчас вам это просто не нужно.
    Ответ написан
  • Что можно сделать на одностраничниках с помощью JavaScript?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Попробуйте реализовать тостер без бэкэнда (например на firebase) как одностроничное приложение. Или любое другое web-приложение. И прикинте что там будет на JS (по сути все).
    Ответ написан
  • Как по максимуму использовать Bootstrap 3 на Symfony 3?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    1. в этом нет смысла. Можно выделить critical-path css и хватит.
    2. это делается не при помощи бандлов а при помощи всяких инструментов для сборки фронтэнда.
    3. тут тоже симфони не причем.

    Короч рецепт успеха - фронтэнд отдельно, бэкэнд отдельно.
    Ответ написан
  • Как использовать рефлексию для метода?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    чем вас не устраивает call_user_func_array?

    p.s. ответ на ваш вопрос есть в документации по рефлексии.
    Ответ написан
  • Использование getter снижает производительность приложения?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    новых циклов $digest конкретно геттер не вызывает.

    В вашем же примере на каждый вызов геттера формируется абсолютно новый массив, и сравнение по ссылке он завалит. При этом сравнение это происходит на каждый $digest цикл. То есть на каждый $digest цикл (при отсутствии deep watch) будет происходить запуск ватчеров. Это единственный риск поскольку избавиться от этого можно только через deep watch а вот эта штука уже серьезно так бьет по производительности.

    Ну и это не говоря о том что на каждый $digest цикл будет дергаться ваш сервис. Вместо этого стоило дергуть сервис один раз и заменять данные в контроллере только тогда когда нужно.

    Если брать современные подходы, то мы вообще должны вынести все получение состояния из контроллеров (компонентов) наружу, например в ресолверы и мэпить все на проперти компонентов. Там уже геттеры/сеттеры хорошо подходят, но только те геттеры/сеттеры которые на уровне языка а не "методы". Это легче тестить, проще поддерживать и в целом открывает большой простор для дальнейшей архитектурной вакханалии.
    Ответ написан
  • Стоит ли использовать везде БЭМ нэйминг?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    если вы не используете БЭМ а только нейминг - то точно нет. Если вы используете БЭМ - то возможно, зависит от того нужно оно вам или нет.
    Ответ написан
  • Как переопределить класс в Laravel?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    вам не нужно это делать. Open-Close принцип. Все можно решить без "переопределений", это только в yii такая чушь.
    Ответ написан
  • Как пользоваться angular2-jwt?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Есть ли возможность пользоваться этим без подключения библиотеки разработчика


    Да. Либа самодостаточна.

    Может кто пользовался и может скинуть ссылки на примеры?


    Там все в ридми в принципе расписано как что юзать.

    import { tokenNotExpired, JWTHelper } from 'angular2-jwt';
    
    const token = 'some jwt token';
    const jwtHelper = new JWTHelper;
    
    if (tokenNotExpired(token)) {
        // everything ok
    }
    
    const payload = jwtHelper.decodeToken(token);


    это минимальный набор фич. Там есть больше, интеграция с Http сервисом и т.д.
    Ответ написан
  • Как правильно сделать раздельно front на angular и back на laravel?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Полистал немного ответы в сети, но что-то как-то всё размылено.


    бэкэнд отдельно, фронтэнд отдельно. Можете даже в отдельные репозитории это дело запихнуть что бы понятнее было. Общение - по HTTP API (JSON RPC, REST, что-хотите). И никаких проблем, никакой каши.
    Ответ написан