Обновить
29
Уманский Леонид@splatt

Пользователь

15
Подписчики
Отправить сообщение

Я не согласен с вашей аналогией. React, Angular, Vue, решают типовые инженерные задачи.
Управление командой — это не типовая инженерная задача и не наука, это soft skills. Каждый сотрнудник индивидуален, к каждому нужен свой подход. Кто-то умеет и хочет подстраиваться под команду, а кто-то наоборот, гораздо производительнее если его не трогают.


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

Я считаю что вы делаете две потенциальные ошибки.


Во-первых, вы строите всю архитектуру на предположении о том, что у вас может одновременно показываться только одна менюшка и это требование никогда не изменится. Но завтра к вам приходит дизайнер / заказчик и просит сделать drag-and-drop между менюшками, и оказывается что во время перетаскивания надо показать обе одновременно. И в такой момент вы понимаете, что весь код придется для этого выкинуть / переписать с нуля, потому что само понятие машины состояний тут неприменимо (раз может быть несколько состояний одновременно).


Во-вторых, в самом switch-case, конечно, ничего страшного нет, но как только добавится логика, анимации переключения между меню итд, появятся классы типа State, StateTransition и прочих артефактов спагетти-стейт машин, и проблема #1 станет еще хуже.


Как по мне, так хорошо установленные паттерны вроде MVC отлично подойдут здесь. Каждое меню или подменю имеет свою пару Controller — View. Controller отвечает за логику и делает вызовы в сервисы, View — за представление (шаблон меню, анимации). За переключение подменю может отвечать одна функция, которая при разворачивании контент-меню закрывает остальные:


// IMenuController.cs:
interface IMenuController
{
    bool IsOpen;
    void Open();
    void Close();
}

//  TopMenuController.cs:
class TopMenuController : IMenuController, INestedMenuContainer
{
    private IMenuController[] _submenus;

    public void OpenNestedMenu(int index)
    {
        for (int i=0; i<_submenus.Length; i++)
        { 
            IMenuController submenu = _submenus[i];
            if(i == index && !submenu.IsOpen)
            {
                 submenu.Open();
            }
            else if(submenu.IsOpen)
            {
                 submenu.Close();
            }
        }
    }

    // ...
}

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


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

Каждый сервис FSA не сильно отличается от монолитных FSA. Разбивая логику на сервисы, не забывая о принципе единой ответственности и SOLID в целом, вы быстро обнаружите, что FSA вам не нужны.


Приведите конкретный пример функционала и я приведу вам пример как сделать его на обычном OOP, без всяких FSA.

Ну, я говорил об играх. Понятное дело, за пределами игр есть ряд узкоспециализированных задач и алгоритмов где FSA применимы. Но для геймплей логики их использовать — это зло.

IMO, Finite State Machines — это антипаттерн похуже синглотонов. Он имеет очень узкое применение — анимация и AI, использовать его где либо еще — моветон. За годы работы в геймдеве, я не видел ни одной нормальной реализации FSA которая бы не раздулась в неподдерживоемое спагетти.


Переписать толком можно легко, есть куча паттернов и подходов, начиная классическими вроде MVC / MVVM (которые отлично подходят для UI-driven и 2d игр, с теми или иными изменениями), и заканчиая Entity Component System и Data Oriented Design.


Я считаю, что в таких ситуацях гораздо уместнее писать Service-Centric код и Inversion of Control. Вместо монолитной машины состояний, состояние игры описывается набором сервисов. Каждый сервис имеет свое сосотояние отвечает за что-то одно и только одно, например: анимация, диалоги, инвентарь, квесты, прогресс игрока, сохранения, аутентификация итд.
Сервисы слабо связаны (через интерфейс) и общаются друг с другом по минимуму. Соответственно, ожидания каждого сервиса так же описываются через интерфейс / контракт, например, сервис диалогов может обращаться к сервису интвентаря что бы узнать, имеется ли в наличии предмет, требуемый для выполнения квеста, итд (InventoryService.HasItem(...)).
Логика каждого сервиса может быть протестирована Unit и Integration тестами.

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

Проверка целостности 7z.dll это очень смешно.
Помню еще в начале-середине 2000ых, так обходили кривые корейские античиты, которые преимущественно боролись с DLL Injection с помощью проверки целостности Import Address Table.
Обход: скачивались исходники соответствующей версии 7zip, пересобирались с нужными изменениями, и клались в папку с игрой :P

Собираю так проект на Unity. По сути — практически бесплатный аналог Unity Cloud Build (если иметь Unity Pro то можно и на бесплатных агентах MS и не понимать виртуалку, но тогда придется при каждом билде ставить движок)

Изменения крутые и полезные.
Очень хотелось бы что бы исправили концептуальные проблемы языка, даже если это означает python 4 и сломанную обратную совместимость.


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

Вы путаете время реакции и время отклика на действие игрока.
Можете выставить здесь 100мс и покликать. Представьте, у вас 2d шутер, и что вам нужно попадать по быстро движущемся целям, и ваша игра станет невыносимой.


А теперь представьте, что данный лаг происходит всегда, в том числе при повороте камеры.

Мониторы и зарядки в сетевой фильтр, а его в розетку?

Можно сделать как в Valve, у которых все рабочие столы мобильные.

Не критикуя статью, покритикую подход.
Я считаю что глобальные аггрегаторы событий нарушают принципы SOLID.
За 6 лет работы с Unity я не видел ни одного проекта, в котором глобальные аггрегаторы событий оправдывали бы себя. В основном все заканчивается спагетти кодом с кучей неявных зависимостей.


Про re-usability кода можно вообще забыть — любой процесс переноса модуля в другой проект заканчивается жестким рефакторингом с поиском по всему проекту, где и что на что подписано.


Этим, кстати, на мой взгляд страдают JS фреймворки и дизайны вроде React / Redux. Все отлично работает, когда у вас TODO приложение с двумя событиями. А когда у вас команда на 50 человек, тысячи классов и событий, все это становится очень трудно поддерживать.

Человек не выбирает, в каком государстве ему рождаться.
Пользоваться или не пользоваться YouTube, каждый решает сам для себя.
Тем более что в данном примере, YouTube не банит видео (хотя следовало бы), а просто отказывается платить вам деньги. Я не считаю это цензурой.

apt-get install в Debian прекрасен ровно до тех пор, пока вам не понадобилось с его помощью поставить новый софт.
apt-get install python3 в Debian устанавливает 3.5.3 (2015й год)
apt-get install python3 в Ubuntu устанавливает 3.6.6 (2016й год)


Смотрим в календарь, видим что на дворе 2019й. Наливаем чай и идем собирать из исходников, подключать альтернативные репозитории или прикручивать pyenv.


DontBreakDebian говорит вам о том, что новый софт вам "не нужен" потому что он "не протестирован", ведь ребята из Debian лучше вас знают, что вам нужно а что нет. Ведь вам нужна надежность. Что довольно иронично, учитывая что некоторые пакеты там настолько старые, что они просто не работают.

Советую посмотреть на Dependency Injection и DI / IoC фреймворки вроде ZenJect (линк).
Знаю, что для новичка это не простая концепция, но она имеет большое количество преимуществ перед синглтонами/статик классами/DontDestroyOnLoad.


Данный подход позволит сделать единую точку входа в приложение, а для хранения данных пользователя вместо singleton объекта можно использовать сервис (который потом можно заинъектить в необходимые вам скрипты):


public interface IGameDataService
{
    public int DifficultyLevel { get; set; }
}

public class EnemyInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        // IGameDataService будет автоматически инъекцировано в зависимые классы
        // включая другие сцены, если использован Scene Container Parenting
        Container.Bind<IGameDataService>().To<GameDataService>().AsSingleton();
    }
}

public class EnemyFactory : IEnemyFactory
{
    private readonly IGameDataService _gameDataService;

    // Зависимость будет добавлена в конструктор автоматически при резолвинге EnemyFactory
    // Для инъекции в MonoBehavior, можно добавить специальный компонент ZenjectBinding и аттрибут [Inject]
    public EnemyFactory(IGameDataService gameDataService)
    {
        _gameDataService = gameDataService;
    } 

    public void SpawnEnemy(string enemyName)
    {
         var level = _gameDataService.DifficultyLevel;
         ...
         var enemy = GameObject.Instantiate(...).GetComponent<IEnemy>();
         enemy.SetLevel(level);
    }
}

В идеале, GameObject'ы и MonoBehavior'ы — для объектов игрового мира. Для всего остального есть обычный C#.

Компанию переименовали из Tesla Motors, Inc в Tesla, Inc в начале 2017 года. В статье речь об авто, которую продали в 2017м (чек датирован декабрем 2017го, но в целом кому выписан чек это не так важно).

На прошлой неделе на Google Pixel 2 приехал апдейт с Google Call Screening, который на 100% решает проблему спам-звонков, которая заключается не в самих звонках, а в том, что людям приходится снимать трубку, если они ждут звонка от курьера/рекрутера/кого угодно.


Уже поймал таким образом пару спамеров и очень смешно смотреть как они пытаются поговорить с автоответчиком.

В западных компаниях НИКОГДА, повторю, НИКОГДА не будут звонить в вашу предыдущую компанию во время background check. Попросят список recommendations/references с телефонами/emailами, и уже из указанного случайно позвонят или (что скорее всего) отправят email с просьбой дать характеристику.

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

Информация

В рейтинге
Не участвует
Откуда
Los Angeles, California, США
Дата рождения
Зарегистрирован
Активность