Белтар, Tag — штука хорошая, но зачастую одного числа не хватает, поэтому использую его крайне редко. И битовые маски в десятичной системе счисления — это не тот код, в котором я хотел бы разбираться…
В твоём случае предпочёл бы код вроде этого:
inline int CTLMASK (int a, int b, int c, int d) { return a | b<<1 | c<<2 | d<<3; } CMap<TControl*, int> map; map .Add(cbYear, CTLMASK(1, 1, 0, 1)) .Add(cbMonth, CTLMASK(1, 0, 0, 1)) // ... .Add(cbCal, CTLMASK(1, 1, 1, 0)); for (int i=0; i<ControlCount; ++i) Controls[i]->Visible = map.Get(Controls[i], 0) & (1 << BG->ItemIndex);
Если бы нужно было расширить до поддержки условно бесконечного числа отчётов, сделал бы не битовую маску, а вектор. Возможно, чуть больше строк кода, но зато вся информация собрана в одном месте, и нет нужды возиться с переводами между системами счисления.
Предложенный Мкивой вариант близок, но предполагает использование индексов элементов управления, а это кошмар, который убьёшься поддерживать.
Beltar, фактически это мой "компромиссный вариант", только у меня состояние контролов - это свойство отчёта(для каждого отчёта задаём массив из 15 значений) , а у тебя - свойство контрола (тег контрола содержит битовый массив из 4 значений). С точки зрения объектной модели предметной области мне мой вариант всё-таки нравится больше. Хотя признаю, что добавлять новые контролы в твоём случае легче (а вот чтобы добавить новый отчёт, надо править теги во всех существующих контролах).
Beltar писал: Матрица 4х15 проще, но ведь ее еще надо хранить как константу. Т. е. 4 стр на ее объявление и опять-таки забивать в тег номер контрола, обращаясь...
Так поэтому я и выбрал компромиссный вариант. Матрица в этом случае разивается на строки, и для каждого отчёта такая строка хранится как свойство этого отчёта.
Кстати, ты немного лукавишь. Теги контролам ведь тоже нужно задавать.
public const bool[] _otchDefault = new bool[] {0, 0, 0, 0, 0, 0...}
public const bool[] _otch1 = new bool[] {0, 1, 0, 0, 1, 0...}
public const bool[] _otch2 = new bool[] {0, 1, 0, 0, 1, 0...}
public const bool[] _otch3 = new bool[] {0, 1, 0, 0, 1, 0...}
private void TfmReports_OnClick(object sender, CommandEventArgs e)
{
switch (e.CommandArgument)
{
case "0": EnableDisableControls(_otch1); break;
case "1": EnableDisableControls(_otch2); break;
case "2": EnableDisableControls(_otch3); break;
default: EnableDisableControls(_otchDefault); break;
}
}
На самом деле, конечно, для каждого отчёта хорошо бы сделать свой класс, а битовая маска в таком случае будет одним из свойств класса.
P.S. И ещё.Beltar, Athari, я поражён вашей жадностью. Битовые операции и сдвиги в описании интерфейса - это... Нет слов. Вам что, 100 байтов жалко? Или вы до сих пор для спектрума программируете? В тех случаях, когда код не выполняется в цикле по сто раз в секунду, главное требование - простота восприятия человеком. А битовые операции таким свойством отродясь не обладали.
На самом деле, конечно, для каждого отчёта хорошо бы сделать свой класс, а битовая маска в таком случае будет одним из свойств класса.
Мкива, крайне неудобно. Каждый раз, чтобы задать отчёт, тебе придётся вспоминать индексы всех элементов управления. Жестоко.
Вам что, 100 байтов жалко?
По-моему, биты довольно просты и лаконичны, уж прости сишника. :) К тому же оперируют битами две строки в коде, которые пишутся один раз и больше не трогаются (ну, почти не трогаются).
А битовые операции таким свойством отродясь не обладали.
В две строчки, работающие с битами, лезть особой нужды нет. Добавление отчёта тривиально, включения мозга не требует.
Остальной мой код как раз ориентирован на восприятие человеком, в отличие от твоего. Посмотри, у меня визуально получилась таблица: в столбцах отчёты, в строках элементы управления, на пересечении нули и единицы.
А вот у тебя как раз-таки месиво из битов. Разбиение на одномерные массивы только усложнило код, нисколько не повлияв на читаемость.
На самом деле, конечно, для каждого отчёта хорошо бы сделать свой класс, а битовая маска в таком случае будет одним из свойств класса.
Из пушки по воробьям…
Если уж делать ООПно, то тогда бы я делал не голый массив битов, как предлагаешь ты, а карту «элемент управления — режим отображения». Но всё равно это совершенно неоправданно, только код усложнит без какой-либо пользы для дела.
Athari писал:Каждый раз, чтобы задать отчёт, тебе придётся вспоминать индексы всех элементов управления. Жестоко.
Угу. А тебе - вспоминать номер отчёта :) Тут всё зависит от того, что добавляется чаще - контролы или отчёты.
Athari писал: К тому же оперируют битами две строки в коде, которые пишутся один раз и больше не трогаются (ну, почти не трогаются).
Угу. Но чтобы понять код, всё равно нужно разобраться, что они делают. Потому что хороший программист, не разобравшись в коде, не станет добавлять строчки, "Не включая мозг". То есть усложняется поддержка кода не-автором, это существенный недостаток.
Athari писал: Посмотри, у меня визуально получилась таблица: в столбцах отчёты, в строках элементы управления, на пересечении нули и единицы. А вот у тебя как раз-таки месиво из битов. Разбиение на одномерные массивы только усложнило код, нисколько не повлияв на читаемость.
По сути дела у меня та же самая таблица, но не по вертикали, а по горизонтали. Матрица - она и есть матрица, как её не задавай.
Разбиение на строки, как я говорил, сделано из предположения, что в дальнейшем эти строки станут свойством объекта "отчёт". Даже не обязательно создавать такой класс языка программирования. Но, скажем, в архитектурных моделях такой объект будет, и будет его свойство. Совершенно не обязательно объектно-ориентированное моделирование доводить до эквивалентного объектно-ориентированного программирования, модельная сущность не обязана стать классом.
А вот двумерная карта или использованный тобой map мне не нравится тем, что является глобальным свойством всей системы. А таких свойств лучше иметь как можно меньше, по возможности распихивая их "по частям" в разного рода объекты и сущности.
Поэтому все что задано в Object Inspector в код в явном виде не попадает.
Белтар, если считать объём кода, то ты прав. Однако объём информации от перетасовки не изменяется. И не просто информации, а информации, которую надо помнить и анализировать.
Рассмотрим экстремальный пример. :) Делаешь какой-нибудь тупой интерпретируемый язык, а весь реальный код расфасовываешь по свойствам Caption и Text элементов управления. Формально при усложнении работы с элементами управления код в исходнике тебе менять не требуется, только записывать «свойства» в инспекторе объектов. Смотри, кучу строк «сэкономили». ;)
А эстетика!?
ООП — вот это эстетика. А биты и массивы — прагматика.
А вот двумерная карта или использованный тобой map мне не нравится тем, что является глобальным свойством всей системы.
Мкива, я же сказал, как поступил бы, если бы решил чудить с ООПом в целом и инкапсуляцией в частности — у меня была бы карта для каждого класса. Это решает и проблему восприятия, и проблему дизайна.
Однако задача ставилась иначе: решить тривиальную задачу (то бишь не требующую декомпозиции и введения сложных сущностей) наиболее лаконичным способом.
Да, и если решать задачу ООПно, то и доводить надо до ума. Твой способ сложно поддерживать, потому что от программиста при добавлении отчёта потребуется одновременно работать с тремя кусками кода:
1) изучить индексы в функции EnableDisableControls;
2) задать новый константный массив;
3) добавить case в switch;
Если довести до ума мой вариант (в частности, использовать функции с переменным числом аргументов), то изменения придётся вносить только в одном месте, причём никаких индексов помнить не придётся, потому что работа будет вестись только с одним отчётом — создаваемым.
Перекраивал тут свой парсер логов, возникла проблема. Решить ее вроде решил, но решение не очень нравится (подробности по ссылке). Может кто-нибудь предложит лучшее?
Хех... Почти вот закончил на php писать парсер логов nmap'а. Нужно для дипломного проекта :)
Оно работает, но не уверен, что всё так, как надо ;)
Но ещё из-за глючности сети всё таки написал ещё скрипт, который отсылает на мобилу СМС, когда восстанавливается VPN-соединение в инет :)
По началу сделал скрипт проще некуда - с одной строкой кода, но обнаружил, что WinRoute запускает его даже при неудачных попытках соединиться xD
В итоге, пока я ездил перезагружать свитч, мне навалило потом штук 40 (или может больше) сообщений, что якобы, инет заработал :)))
Приехал, исправил.
O darkness, if in thy arms I could rest for a while, and with these earthly eyes see thy dim smile...
mcMillan Just the man in the back Сообщений: 1536 Город: Москва 26.12.2009 14:41
Моя первая проба пера в Delphi. Не судите строго, программы прошу принимать не как вредоносные, а как приколы. Запускать их лучше перед выключением компа т.к. некоторые из них вряд-ли получится закрыть.
P.S. интересно, а в какой раз я пишу это сообщение?
This signature will never appear on this forum, isn't that weird?
Leo Shaka Snow Leopard Сообщений: 698 Город: Иркутск 23.01.2010 14:22
mcMillan, если будет интересно, то первая и третья запустились в вайне(то есть все кроме тех что с окнами). Особенно повеселил летающий пуск в Дебиане^^
"Человек, который исколесил всю Галактику вдоль и поперек, прошел через голод, нужду и лишения, и все-таки имеет при себе полотенце — это человек, с которым можно иметь дело."
Мне судорожные окна понравились XDDDD
Они же чем дальше, тем больше трясутся? 0о
Исчезающие не понравились о0
Хм... подкинуть что ли матери на ноут.. Х)
А, ммм, можно ли как-то сделать, чтобы запуск начался через какое-то время? 0о
Я просто не хочу быть подозреваемой XD