Обфускация 80 уровня
Jul. 13th, 2018 11:06 pmДисклеймер: я все более укрепляюсь во мнении, что автор разбираемого мной кода поставил себе задачу: "написать максимально сложный код, который все еще реально отладить", с коей успешно справился. Один пример, с которого я фалломорфирую уже пять минут.
Дано: есть нить исполнения, которая принимает команды из очереди. Суть команд простая - вызвать либо одну, либо другую функцию с вагоном параметров.
Напрашивается простой вариант - вагон параметров пакуется (для читабельности в json, для скорости в struct), спереди приделывается идентификатор функции, пишется в queue.Queue, а при получении в зависимости от идентификатора вызывается та или иная функция.
А теперь решение. Конструируется объект с методом call(), в который засовывается вагон параметров, после чего весь объект засовывается в очередь (да здравствует pickle, как я понимаю). При этом на каждый тип команды (= метод принимающего класса) есть свой собственный класс. Далее объект достается из очереди принимающим классом, который вызывает метод call() принятого объекта, передавая в качестве аргумента... себя. А метод call... вызывает захардкоженный метод переданного ему объекта, передавая ему протащенный через очередь вагон параметров.
Не, оно так работает, и тащемта эти два способа в машинном-то коде друг от друга не сильно отличаться будут... но, Локи, но нах*я?
И вот оно там все такое. Передача себя в метод другого класса, чтобы другой класс во мне что-то поправил или дописал (кто сказал, инкапсуляция?). Вместо того, чтобы отнаследоваться от системного класса, дописав пару удобных оберток, мы положим этот класс единственной переменной своего класса.
Мой приговор - тысячу Ave, столько же Pater и Credo, и сто раз прочитать про KISS.
Дано: есть нить исполнения, которая принимает команды из очереди. Суть команд простая - вызвать либо одну, либо другую функцию с вагоном параметров.
Напрашивается простой вариант - вагон параметров пакуется (для читабельности в json, для скорости в struct), спереди приделывается идентификатор функции, пишется в queue.Queue, а при получении в зависимости от идентификатора вызывается та или иная функция.
А теперь решение. Конструируется объект с методом call(), в который засовывается вагон параметров, после чего весь объект засовывается в очередь (да здравствует pickle, как я понимаю). При этом на каждый тип команды (= метод принимающего класса) есть свой собственный класс. Далее объект достается из очереди принимающим классом, который вызывает метод call() принятого объекта, передавая в качестве аргумента... себя. А метод call... вызывает захардкоженный метод переданного ему объекта, передавая ему протащенный через очередь вагон параметров.
Не, оно так работает, и тащемта эти два способа в машинном-то коде друг от друга не сильно отличаться будут... но, Локи, но нах*я?
И вот оно там все такое. Передача себя в метод другого класса, чтобы другой класс во мне что-то поправил или дописал (кто сказал, инкапсуляция?). Вместо того, чтобы отнаследоваться от системного класса, дописав пару удобных оберток, мы положим этот класс единственной переменной своего класса.
Мой приговор - тысячу Ave, столько же Pater и Credo, и сто раз прочитать про KISS.