Модульные тестируемые субъекты в игре на C ++ - PullRequest
0 голосов
/ 30 мая 2020

Я работаю над большой устаревшей базой кода, которая использует паттерн Актер, наследование и множество синглтонов.

Это пример того, как может выглядеть код для «игрового объекта» (C ++ i sh псевдокод):

class MyActor : Actor {
    void Update() override {
        auto asset = ResourceLoader::Instance().Load(“assetName”);
        // use asset
    }
}

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

class MyActor: Actor {
    MyActor(ResourceLoader& loader): m_loader(loader){}
    void Update() override {
        auto asset = m_loader.Load(“assetName”);
    }
    ResourceLoader& m_loader;
}

Хорошее улучшение! Загрузчик теперь можно легко заменить на макет, и поэтому код можно тестировать.

Но этот шаблон на самом деле не жизнеспособен, потому что есть еще много синглтонов, к которым нужно получить доступ. Классу придется добавить около 10 новых членов к этим различным службам, и это сделает sizeof (MyActor) слишком большим. В игре тысячи актеров, поэтому увеличение размера класса приведет к быстрому увеличению использования оперативной памяти.

Итак, теперь я ищу альтернативные решения. Вот мои текущие идеи:

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