Alexey's profileLife vs. ProgrammingPhotosBlogListsMore Tools Help

Blog


    May 31

    Команда, просто команда.

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

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

    Задача стара как мир, но каких только способов решения ее не увидишь... Сегодня, например, я даже столкнулся с таким совершенно экзотическим способом: разработчик наследовался от кнопки для того, чтобы определить ее поведение. То есть у него были такие наследники, как, скажем, SettingsButton, DeleteButton и т.д. Экземпляры этих кнопок создавались и передавались контролу, который их внутри себя размещал.

    Сначала я не знал, смеяться мне или плакать, но потом решил, что, поскольку создавшего это я не знаю, то все же посмеюсь. Заодно и напишу о том, как эту задачу правильно решать. Ничего нового я не скажу и те, кто при слове "Команда" уже все поняли, дальше могут не читать.

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

    public abstract class CommandBase
    {
       
    public abstract string Title { get; set; }
       
    public abstract void Execute();
    }


    Потом мы просто создаем отдельный класс-команду для каждой ситуации, с разной логикой, разными параметрами конструктора и т.д. (UserDeleteCommand, StartGameCommand, etc).
    Сделав это мы получим набор функциональности, которую обеспечивает наше приложение. Теперь давайте позволим пользователю воспользоваться этим набором.

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

    private void RegisterButton(CommandBase command)
    {
       
    //Создадим пользовательский элемент, в данном случае - кнопку
       
    Button btn = new Button();
        btn.Text = command.Title;

        //при нажатии на кнопку запускается команда
       
    btn.Click += delegate(object sender, EventArgs e) { command.Execute(); };

        //добавим кнопку на панель кнопок
       
    _buttonsPanel.Controls.Add(btn);
    }

    А потом просто использовать этот метод там, где мы "наполняем" пользовательский интерфейс:

    MyProfileCommand

    profileCmd = new MyProfileCommand(currentUser);
    Navigator.RegisterButton(profileCmd);
    MainMenu.RegisterMenu(profileCmd);

    Создание пользовательского элемента на основании команды можно вынести в фабрику, в сервис или придумать что-то еще. Важно то, что мы не делаем в нашем коде микс из логики и элементов управления и то, что мы всегда можем использовать одну и ту же команду несколько раз, вызывая ее из разных элементов пользовательского интерфейса или из недр нашего приложения, поведение легко контроллируется, код легко поддерживается.

    Здесь я привел наверное самый примитивный вариант использования этого простого подхода. Немного расширив его можно получить очень неплохой результат, но, прошу вас, не прибегайте в ваших приложениях ко всяческим экзотическим подходам в виде наследования кнопок, хранилища делегатов или писанине всей логики приложения в функциях типа button1_Click(..) :)
    Подумайте, а вдруг этот код еще кому-то читать придется?!

    May 26

    Новый ноутбук: выбор сделан.

    Dell Inspiron 9400  Несколько месяцев я размышлял о том, когда и какой ноутбук покупать.

    Дело в том, что после того, как у меня потрескались корпуса у КПК Acer N30 и ноутбука Acer 5021, связываться с Acer'ом больше не хотелось.

    Связываться с AMD Turion после того, как жарким бельгийским летом он просто вырубал комп без предупреждения тоже не хотелось.

    В конце концов выбор пал на Dell Inspiron 9400 со следующими параметрами:

    CPU: Core2 Duo 2.00GHz
    Display: 17" широкоформатный, 1920х1200
    HDD: 160GB
    RAM: 2GB (667)
    Video: ATI Mob. Radeon x1400 256MB
    WiFi: версия спецификации "n", на будущее, не люблю провода
    BlueTooth: встроенный

    Все драйверы ко всем устройствам уже были установлены с дистрибутивом Висты и работают прекрасно.

    Из полезного софта было установлено Windows Vista Home Premium, Roxio DVD Studio, Dell MediaDirect.
    Из бесполезного софта было снесено: Corel PhotoPaint Trial, McCafe AntiVirus, Google Desktop, Google Toolbar.

    Весь софт, который был нужен, установился и работает без проблем: Nikon Capture NX, Ulead VideoStudio 11, Abby Lingvo 12 и т.д.

    В общем, покупкой я доволен.

    Вот еще, меня спрашивают, насколько это удобно - такое разрешение на 17-дюймовой матрице. На мой взгляд - очень даже удобно. По своим характеристикам (чекткость, яркость) эта матрица превосходит матрицы ноутов HP и Acer'а, которые у нас есть. И, хотя на том же Acer'е матрица очень даже неплохая, разница ощутима, когда ставишь ноуты рядом.
    Кроме того, фотографии, обработанные на том же Acer'е, выглядят на Dell'e как-то насыщенней и, что хочется отметить, четче. Иногда даже создается впечатление несколько излишнеей четкости, быть может с непривычки.

    Что же касается работы.. Час назад установил на ноут Visual Studio "Orcas" Beta1. Просто супер - я могу открыть все нужные мне панели и при этом остается еще полно места для написания кода. Очень здорово.

    Остается только поблагодарить Dell за их работу: заказ делали по телефону, просили изменить конфигурацию (матрица, процессор, память и т.д) а так же, самое главное, англоязычный софт и QWERTY-клавиатуру (местные используют AZERTY).
    Заказ был принят за 10 минут, оплачен банковским переводом и за 4 дня доставлен UPSом прямо домой.

    За все это с меня содрали 1564 евро, цена для ноута такой конфигурации очень даже ничего.

    Счастливого ему "плавания" ;)

    May 20

    Smart Client Software Factory - May Release

    Буду краток.

    Майский релиз SCSF. Поддержка WPF, CAB, улучшенный гайдлайн и т.д.

    Брать можно здесь: http://www.codeplex.com/smartclient

     

    May 07

    Электронные платежи: российская действительность.

    Я вот решил проапгрейдить Лингво до 12-й версии. А еще есть такой магазин - СофтКей.
    Вообще, они, вроде, хорошие ребята. Хотя бы потому, что другого способа не заказывать коробку почтой, а просто скачать интересующий меня продукт я не нашел. А нашел СофтКей.

    Поэтому пошел в этот СофтКей, сказал ему, что хочу Лингво, а платить буду карточкой Visa.
    Все прошло хорошо, платеж прошел мгновенно, я получил СМС о том, что деньги с меня сняли и два письма от СофтКея.

    К сожалению, ключа внутри не оказалось, равно как и ссылки, откуда можно скачать купленное.
    Подождал. Ссылки нет. Почитал письма, залогинился, смотрю статус заказа. Смотрю, значит, а там написано, что заказ не оплачен.
    Странно, думаю. Деньги-то сняли. Обычно после этого сразу прилетает "спасибо, дорогой клиент" и ссылки, и ключи, и бонус-паки.. Чай не в первый раз.
    А тут - тишина.

    Полез читать про оплату. Вроде все должно быть ОК.
    Полез читать FAQ. А там и написано:

    При первой оплате данного клиента пластиковой карточкой проходит телефонная авторизация, т.е. Вам звонят и подтверждают Ваш заказ. Только после нее статус Вашего заказа считается оплаченным. Магазин информирует Вас, что телефонная авторизация проводится нашими операторами с 10 до 19 часов по рабочим дням. Просьба при оформлении заказа указывать телефон, по которому Вам можно дозвониться в эти часы.

    Ужас какой. Вообще-то я с ними разговаривать не хотел. Я ввел свой номер карты, я ввел CCV. Я хотел продукт, а говорить по телефону, да еще и в международном роуминге не хотел совершенно.

    И как быть, если я немой?! Что, немым, получается, никак нельзя купить продукт?

    Выходит, что быстро оплатив картой продукт я теперь должен ждать, когда проснутся менеджеры и поимеют удовольствие общения со мной...

    Вот такая она, российская действительность. У кого только тут покупал - не видел такого...

    May 06

    День рождения Королевы Беатрикс

    Оранжевые мамы
    Оранжевым ребятам
    Оранжевые песни
    Оранжево поют 

    День рождения Королевы отмечается в Нидерландах 30-го апреля не смотря на то, что родилась королева Беатрикс где-то в середине лета. Объясняется это тем, что день рождения предыдущей королевы, матери нынешней, был именно 30-го апреля. В этот же день она отреклась от престола и ее место заняла Беатрикс. Вот так, королевы меняются, а праздник решили не переносить. Какая разница, на самом деле, что праздновать - коронацию или день рождения? Да и вообще, совместить можно.

    В этот день по всем крупным городам Нидерландов с утра устраиваются народные гуляния, ярмарки и распродажи. Любой человек может выйти на улицу и что-нибудь продать, при этом он не обязан платить налогов. Магазины тоже могут торговать в "безналоговом" режиме, правда, практически все они в праздник закрыты. Но на тех немногих, что все же работают, можно обнаружить объявления: "Сегодня в течение всего дня скидка 25%".

    Мы приехали в Амстердам утром, часов около 11, и город был уже полон. Нам сразу же выдали какие-то (оранжевые) рюкзачки, кстати, идея очень полезная - кто-то складывал туда мусор, кто-то - приобретенные на ярмарке вещи..

    Нет спроса... Еще раз доказал всем, что похож на немца Гуляем тут все...

    Народ стекался в столицу до самого вечера - по улице от вокзала в центр шел сплошной (оранжевый) поток в течение всего дня.

    Каналы в старом Асмтердаме были запружены лодками, лодочками, суденышками, практически в каждом из которых играла музыка, (оранжевые) люди устраивали пикники, а на некоторых, размерами побольше, устраивались целые дискотеки. Их было так много, что периодически даже возникали пробки на воде.

    На канале Посторонись!

    Кстати, обратил внимание на ряд местных развлечений, интересующиеся могут перенять.

    1. После того, как вы с друзьями "уговорили" бутылочку чего-нибудь, положите ее на пол и попробуйте поднять с помощью нехитрого приспособления: палка, к ней привязана веревка, на конце которой пластмассовое кольцо диаметром 10-15 сантиметров. Идея в том, чтобы держась за палку "зацепить" горлышко кольцом и привести лежащую бутылку в вертикальное положение.
    2. Ваши друзья никогда не хотели забросать Вас яйцами в прямом смысле этого слова? Предоставьте им эту возможность! Чтобы мне долго не описывать, а вам - не вникать, приведу фото:

      Где-то шагах в 10 от обстреливаемого находится "огневой рубеж", который представляет из себя стол с коробками яиц. Попадают редко. Но попадают.

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

    В общем, гуляния прошли хорошо, весело. В очередной раз порадовало то, что все вокруг было мирно, никаких тебе "бычков-братков" с заплывшими от пива глазами (я все никак привыкнуть не могу к этому факту).

    Однако, в Амстердам придется ехать еще раз для того, чтобы увидеть его без ярко-оранжевой толпы, без шума, без ярмарок.. В общем, для того, чтобы  увидеть, собственно, сам Амстердам таким, какой он есть, вот таким:

    Но это будет уже другая поездка, в другое время и с другими целями...

     Ночь и половину следующего дня до отъезда мы провели в Гааге - в городе, где находится королевский дворец и где живет сама виновница торжества - Королева Беатрикс.

    Гуляний там уже не было, а 1-е мая нидерландцы не празднуют, так что время выдалось спокойным для того, чтобы прогуляться до дворца, побродить по берегу моря и подивиться странной нидерландской скульптуре (видимо, у них свой Церетели есть).

    Королевский дворец. Штандард поднят - королева дома.Пляж Гааги. 
    Я вверх по лестнице пошел - и человека там нашел. Его там не было вчера, как я хочу, чтоб он ушел...Скульптура Гааги: Посадили монстра на кол, оторвали монстру все, что смогли...
    May 04

    Первомайские выходные: Франция.

    На прошлые выходные выпало покататься по близлежащим странам. Соответственно, два дня мы катались по Франции, поставив себе целью посетить столько замков, сколько успеем (успели три) и оставшиеся два дня провели в Нидерландах, празднуя день рождения королевы Беатрикс и гуляя по Гааге.

    Для начала расскажу поездке во французские замках, коих мы, как я уже сказал, посетили три: Фонтенбло, Блуа и Амбуаз. Замки эти оказались настолько разными, что я даже подумал, что вот бы объединить достоинства трех в одном.

    Фонтенбло, огромный старый замок времен Филипа Первого, удивил заброшенностью и пустынностью своей территории. Но при этом его "содержимое" оказалось просто сплошным произведением искусства. Несколько снимков:

    Коридор в замке Фонтенбло Комната в замке Фонтенбло
    Потолки и стены - они такие Залы Фонтенбло Комната в замке Фонтенбло

    Блуа - замок, который известен двумя вещами.
    Первое - музеем магии, посвященному "отцу современной магии", мсье Робер-Удену. Робер-Уден был первым из магов, который стал давать большие представления в театрах (до него фокусники выступали лишь на ярмарках), первым надел фрак, первый представил свое искусство в "высшем свете".
    Второе - в этом замке убили и сожгли в камине герцога Генриха Гиза, того самого, который имел огромное влияние во Франции и фанатично уничтожал протестантов. И, поскольку он угрожал даже самому королю, Генрих Третий, король Франции, заманил его в Блуа, где и убил.
    Вообще в этом замке много кто еще отметился но все же он был перестроен в 19-м веке и по этой причине состоит из двух совершенно несочетаемых на вид частей, одна из которых выполнена из красного кирпича.

    Внутренний двор замка Блуа Обновленный замок Блуа
    Убийство герцога Гиза Спальня, в которой умерла Екатерина Медичи

    Амбуаз тоже отличился в истории. Здесь была поставлена точка в первой войне между гугенотами и католиками - заключен амбуазский мир. Здесь же прятался король Франсиск Второй во времена заговора гугенотов, которым надоело преследование. Гугеноты хотели избавиться от фанатичных Гизов и, если удастся, убрать Франсиска Второго от власти и передать эту самую власть Бурбонам. Но замок там крепкий, высокий, так что нападение было отбито, а головы нападающих украсили ворота и стены замка...
    А еще над этим замком трудился Леонардо ДаВинчи, который завещал похоронить себя там, что и было выполнено.
    Нам же этот замок понравился своей опрятной и красивой территорией :)

    "Парадный вход" в замок Амбуаз. Индус. Я сначала думал, что он медитирует под деревом. А он играл с PocketPC...
    Памятник Леонардо ДаВинчи.

    Кроме замков в те дни мы успели погулять по Орлеану (Жанну д'Арк помните?) и поразмышлять о тех скудных клочках огромной и, как теперь начинаем понимать, очень интересной истории, которые остались в наших головах..

    Лично я пришел к выводу, что вся путанница в истории тех веков - из-за Генрихов. Уж очень много их было и в Англии и во Франции, и королей и герцогов :)
    Да и наша "российская действительность" путаницы добавляет. Мы-то их всех знаем как Генрихов, поди разберись где кто. Почему было не называть французских Генрихов так, как называют их французы (Анри), а английских так, как называют их англичане (Генри)?!
    Было бы все понятно. Анри Третий. Генри Четвертый. Сразу ясно, кто откуда и из какого периода. А то... :)

    Вооот.. А потом мы поехали в Нидерланды, праздновать день рождения королевы Беатрикс.
    Об этом я напишу в следующем постинге.