Есть длинная колбаса сишного кода, которая оперирует контекстами, хендлами и массивами
(типичный пример)
При переписывании в с++ код по уму надо каждую сущность обернуть в с++ объект и оперировать с ним,
но опустим данный подход.
Я хочу разбить код на небольшие методы по 5-10 строк, не более.
Очевидно, появляется много входящих и выходящих переменных.
Можно
а) прописать все исходящие переменные в поля класса и работать с ними.
или
б) явным образом получать при выходе из функции все значения в виде некоей структуры.
В первом варианте страдает как читаемость кода, так и связность.
Второй вариант куда более элегантен,прекрасно тестируем но складывается ощущение,
что это не ООП подход и можно сделать как-то иначе.
А как бы сделали вы?
Re: Баланс между хранением переменных в полях класса и красотой кода.
SO_>Я хочу разбить код на небольшие методы по 5-10 строк, не более.
Какая конечная цель? Если цель — визуально сделать более читаемо, то как вариант, разбить на блоки:
void main()
{
int width;
int height;
...
// open input file
{
...
}
// setup demuxer
{
...
}
// setup decoder
{
...
}
// process file
{
...
}
// close files and buffers
{
...
}
// error handling
{
...
}
}
А так — вполне себе обычный C-шный код для сэмпла.
Патриот здравого смысла
Re[2]: Баланс между хранением переменных в полях класса и красотой кода.
Здравствуйте, DiPaolo, Вы писали:
SO_>>Я хочу разбить код на небольшие методы по 5-10 строк, не более. DP>Какая конечная цель? Если цель — визуально сделать более читаемо, то как вариант, разбить на блоки:
...
DP>А так — вполне себе обычный C-шный код для сэмпла.
Цель — обернуть с код в с++ оболочку. Не люблю колбасы.
Причем, хочется обойтись малыми усилиями и не лепить по С++ классу на каждый С тип.
Re[3]: Баланс между хранением переменных в полях класса и красотой кода.
class FileDecoder
{
public:
int openFile();
int processFile();
int done();
int dumpOutputLog();
private:
int openInputFile();
int openOutputFile();
int setupDemuxer();
int setupDecoder();
int closeDemuxer();
int closeDecoder();
private:
FILE *video_dst_file = NULL;
FILE *audio_dst_file = NULL;
uint8_t *video_dst_data[4] = {NULL};
int video_dst_linesize[4];
int video_dst_bufsize;
...
}
void main()
{
int width;
int height;
...
FileDecoder decoder(...);
decoder.open(inputFile);
decoder.processFile();
decoder.dumpOutputLog();
}
Патриот здравого смысла
Re[4]: Баланс между хранением переменных в полях класса и красотой кода.
Здравствуйте, SomeOne_TT, Вы писали:
SO_>Я хочу разбить код на небольшие методы по 5-10 строк, не более. SO_>... SO_>А как бы сделали вы?
Я бы не разбивал код на методы по 5-10 строк. Посмотрел бы на колбасу, и по обстоятельствам принял решение о том, что вынести, а что так и оставить колбасой.
Борьба с Цикломатической сложностью — весьма вредный фетиш. Один длинный метод бывает на порядок проще понимать, развивать и сопровождать, чем то же самое, но нарезанное на десятки кусочков.
Что до двух описанных альтернатив, то каждая из них по-своему ужасна. Во втором варианте, кстати, его неООПшность — самая маленькая проблема (ООП — тоже фетиш, и тоже весьма вредный).
Re[2]: Баланс между хранением переменных в полях класса и красотой кода.
V>Что до двух описанных альтернатив, то каждая из них по-своему ужасна. Во втором варианте, кстати, его неООПшность — самая маленькая проблема (ООП — тоже фетиш, и тоже весьма вредный).
Согласен, пример на С прекрасно читается, однако тестировать его сложнее, чем набор функций.
Что ж, за неимением лучшего, примем колбасу за основу.
Благодарю Voblin, DiPaolo.
Re: Баланс между хранением переменных в полях класса и красотой кода.
Здравствуйте, SomeOne_TT, Вы писали:
SO_>б) явным образом получать при выходе из функции все значения в виде некоей структуры.
SO_>Второй вариант куда более элегантен,прекрасно тестируем но складывается ощущение, SO_>что это не ООП подход и можно сделать как-то иначе.
Здравствуйте, SomeOne_TT, Вы писали:
SO_>Второй вариант куда более элегантен,прекрасно тестируем но складывается ощущение, SO_>что это не ООП подход и можно сделать как-то иначе. SO_>А как бы сделали вы?
Постарался бы сделать комбинацию двух подходов. С большим упором на второй подход. После некоторого опыта пришло понимание, что ООП ни черта не панацея, и не нужно делать ООП только ради того, чтоб было ООП. Соответственно максимум логики на коротких простых функциях без сайд эффектов. У которых один вход и один выход, в качестве входа и выхода могут быть структуры.
Которые прекрасно тестируются и повторно используются. А на те случаи, когда это не работает (например если так делать, то нужно до фига параметров передавать в функцию) — использовать классы. И стараться соблюдать баланс. Основной критерий — писать как можно меньше кода. И чтоб при этом еще и протестить можно было хотя б основной функционал. И чтоб тесты тоже не были монструозными . Ну а если еще и перфоманс нужен максимальный, начал бы жертвовать чем либо, возможно бы уменьшил процент функций без сайд эффектов в пользу методов. Но в любом случае бы дробил на мелкие куски логику.
Re: Баланс между хранением переменных в полях класса и красотой кода.
В общем и целом колбасу удалось порезать на куски, в полях класса ничего не хранится,
ключевую роль выполняли unique_ptr с самодельными делетерами, что позволило ограничиться локальными переменными.