Andy Melnikov (nponeccop) wrote,
Andy Melnikov
nponeccop

Category:

Абстрактная фабрика синглтонов-2

Поскольку все ответы были в стиле кармановского пункта 6 https://www.atraining.ru/trainers/karmanov/hint/ - "Разбираться в проблеме не нужно, ... – надо просто неправильное заменить на правильное", я сформулирую одновременно более абстрактно и более предметно.

Есть компонент А создающий и дёргающий компонент Б, а компонент Б запускает ракеты и возвращает слово из трёх букв.

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

Классическое решение - сделать, чтобы в тесте компонент А дёргал компонент Б', который будет просто возвращать ожидаемое компонентом А слово из трёх букв, никаких "ракет" при этом не "запуская".

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

Вариант 1 - пусть компонент А не создает объект Б, а принимает его параметром.

В системе будет A(Б), а в тесте A(Б'). Но тут есть недостаток - например если компонент А создаёт Б не напрямую, а создаёт С, который уже создает Б - то С тоже придётся параметризовать.

Ну и для того чтобы этого размножения параметров избежать - используется старый трюк "передаём параметр вглубь, используя глобальную переменную". И мы подходим к варианту 2

Вариант 2 - пусть будет глобальная фабрика БFactory, которая будет производить экземпляры Б или Б'

В системе будет А и Б, без параметров. Может быть даже произвольное количество промежуточных уровней С. Но C будет использовать метод БFactory для конструирования Б. И этот метод будет разным в системе и в тестах.

Но тут недостаток что у нас будет много фабрик - для Б, потом понадобится фабрика для Х, У, ну и т.д. Ну и будут простыни конструирования этих минифабрик при старте системы и в тестах.

Это можно решить вариантом 3.

Вариант 3 - пусть будет одна большая фабрика ФабрикаВсего.

У него есть 2 подварианта

3а - мы просто добавляем в БFactory методы - makeБ, makeХ, makeУ.

3б - мы используем готовую ФабрикуВсего, которых уже написаны тучи.

В варианте 3б у нас вместо двух простыней в пункте 3а - простыни конструирования и простыни виртуальных методов - остаётся только одна простыня конструирования - "регистрация классов в фабрике".

Тут мы избавились от "параметризации всего всем", но для обепечения подменяемости, для каждого подменяемого класса Б нам нужен интефейс IБ. Ну и если у нас классы здорового человека с 1-2 методами - то появляются тучи мелких интерфейсов, ненужных для работы системы, а нужных лишь для работы тестов. Ну то есть код превращается в сплошной бойлерплейт интерфейсов, учитывая, что от бойлерплейта параметров и бойлерплейта фабрик мы избавились.

Тут на помощь (сомнительную, но будем пробовать) приходит Акка, заявляющая что нетипизированность акторов - это не недостаток, а преимущество. В данном случае оно проявляется в том, что если Б - актор, то поскольку всё общение с актором происходит через IDispatch IActor, нам не надо делать тучу этих IБ. И мы приходим к варианту 4.

Вариант 4 - фабрика всего, производящая акторы

Тут только маленькое уточнение, что поскольку для создания актора нужно передать фабрику в ActorOf, мы можем вместо фабрики, вызывающей ActorOf, использовать фабрику аргументов ActorOf, то есть фабрику фабрик. С аналогичными 2 вариантами из п. 3 - то есть наша фабрика или готовая.

Но есть ещё

Вариант 4в - трёхэтажная фабрика из прошлого поста

Она получается, если фабрику фабрик в стиле 4а конструировать готовой фабрикой в стиле 3б. Что даёт нам компактность 3а-фабрики в сочетании с конфигурируемостью 3б-фабрики.
Tags: programming, все пидарасы а я, выебудни
Subscribe

  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 2 comments