CITKIT.ru
3 терабайта свободного софта!
Logo    
IT-рынок Новости мира IT Океан(!) софта на CITKIT.ru Форумы Поступления в библиотеку Учебный центр Курилка
CitForum    CITForum на CD Море(!) аналитической информации! :: CITFORUM.RU
IT-консалтинг Software Engineering Программирование Open Source СУБД Безопасность Internet Сети Операционные системы Hardware

16.05.2005

Google
WWW CITForum.ru

Новости мира IT:

  • 11.05 - Intel создает свою группу по Open Source
  • 11.05 - Банк контролирует использование USB устройств при помощи DeviceLock
  • 11.05 - Microsoft устранила опасную дыру в Windows
  • 11.05 - "Корпорация ОСС" создает антимонопольный альянс операторов IP-телефонии
  • 11.05 - В Mac OS X найдены множественные уязвимости
  • 11.05 - "Билайн" запускает услугу "Мобильная почта"
  • 11.05 - Две критические уязвимости в браузере Firefox 1.0.3
  • 11.05 - IBM покупает начинающую Open Source-компанию Gluecode
  • 11.05 - Microsoft готова к битве с Open Source за школы
  • 11.05 - Sun завершит "открытие" Solaris в ближайшие 45 дней
  • 11.05 - Создатели браузера Firefox выпускают юбилейные монеты в честь 50 миллионов скачанных копий
  • 11.05 - Вышла пятая версия мобильной ОС от Microsoft
  • 11.05 - Поисковые движки умнеют быстрее, чем люди
  • 11.05 - Фишеры постоянно совершенствуются
  • 11.05 - Специалисты прогнозируют появление аналога Google Adsense от "Яндекс"
  • 06.05 - ICANN озаботилась проблемой торговых марок
  • 06.05 - Google патентует сортировку новостей
  • 06.05 - Intel готовит двуядерные процессоры второго поколения
  • 06.05 - Schoolforge-UK и OSC продвигают Open Source в школы
  • 06.05 - Новая версия рекламной программы подстрекает пользователей купить ПО для своего лечения
  • 06.05 - Microsoft продает ряд своих закрытых разработок
  • 06.05 - Google Labs анонсировал ускоритель интернета
  • 06.05 - Microsoft подвешивает пиратам "морковку"
  • 06.05 - В США входят в обиход "интеллектуальные" тележки для супермаркетов
  • 06.05 - Microsoft работает над аналогом PDF
  • 05.05 - Yahoo video search теперь доступен массам
  • 05.05 - Алмазы помогут бороться с хакерами
  • 05.05 - Интернет-охоту хотят запретить
  • 05.05 - Microsoft привлекает блоггеров для теста Longhorn
  • 05.05 - Основатель Red Hat предложил Стиву Джобсу помощь в решении проблемы с торговой маркой
  • 05.05 - Компьютерная система оргкомитета Кубка мира по футболу 2006 года пострадала от червя Sober
  • 04.05 - Cisco Systems представила многофункциональный продукт Adaptive Security Appliance 5500
  • 04.05 - Администрация Евросоюза поддержала идею всеевропейской интернет-библиотеки
  • 04.05 - Компьютерный вирус дарит билеты на чемпионат мира по футболу
  • 04.05 - Лаборатория Касперского: Обзор вирусной активности - апрель 2005
  • 04.05 - Microsoft хочет отсудить у россиянина два домена
  • 04.05 - Сделка между Lenovo и IBM завершена
  • 04.05 - Эпидемия червя Sober.p зафиксирована в Западной Европе
  • 04.05 - Panda Software публикует отчет о вирусной активности за апрель
  • 03.05 - Институт SANS обновил список наиболее опасных уязвимостей

    Архив новостей >>>


  • 2005 г.

    Обзор: первое знакомство с Delphi 2005

    Алексей Вуколов, Елена Филиппова, Игорь Шевченко, «Королевство Delphi»

    Содержание
    1. Первая страница
    2. Редактор кода
    3. Рефакторинг
    4. Unit-тестирование
    5. Компилятор
    6. Отладка
    7. Встроенный Data Explorer

    Первая страница

    После загрузки среды перед нами возникает приветственная страница "Welcome Page". Это новый аналог того самого окошка новостей, которое выглядело довольно неказисто, если ваш компьютер не был подключен к интернету во время работы. Однако не стоит так же сбрасывать со счетов и новый вариант. Кроме ленты новостей (RSS), "Welcome Page" содержит немало полезных ссылок. Во-первых, в самом верху страницы перечислен список проектов, которые вы уже открывали некоторое время назад, с указанием даты последней модификации. Каждая ссылка, естественно, открывает выбранный проект.

    Показать скриншот в отдельном окне

    В левой части страницы подобраны ссылки на справочную информацию, документацию, которая устанавливается на ваш компьютер при инсталяции Delphi2005. Далее идут ссылки в интернет, на страницы компаний-разработчиков, чьи продукты встроены в среду. Например, на страницу Rave Reports, IntraWeb и так далее. И, наконец, ссылки на новостные группы в интернете, BDN и другие страницы Borland-ресурсов. То есть, "Welcome Page", действительно содержит полезную информацию. Может быть, не часто придется ею пользоваться, но и забывать о ней не стоит, может пригодиться.

    Среда предоставляет возможнсть работать как в классическом стиле предыдущих версий Delphi (с отдельными окнами для дизайнера форм, инспектора объектов и т.д.), так и в стиле, максимально приближенном к MS Visual Studio, когда все окна пристыковываются к центральному, в котором можно заниматься дизайном формы или редактированием кода.

    Для того, чтобы привести окна редактирования и палитры компонентов к привычному виду, поэкспериментируйте с настройками Tools | Environment Options | Delphi Options | VCL Designer | Embedded designer и Tools | Environment Options | Tool Pallete.

    В Delphi2005 изменилась справочная система. Изменился не только внешний вид, но внутренняя структура предлагаемой информации.

    На мой взгляд, пользоваться справкой стало намного удобнее.

    Показать скриншот в отдельном окне

    Появилась возможность настраивать цвета для Object Inspector, смотритеTools | Environment Options | Object Inspector.

    [ К содержанию ]

    Редактор кода

    С редактором кода стало работать намного удобнее.

    Комментирование блока текста

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

    В новой IDE это делается легким движением руки. Выделяем текст, нажимаем клавиши [Ctrl+/] и весь выделенный код оказался закомментирован. Обратная операция делается точно так же. На всякий случай напомню, почему это лучше, чем обычные скобки {} в начале и конце куска кода. В случае использования в начале каждой строки двойного слеша нет никакой нужды заботиться о вложенных комментариях, которые могут уже быть в выделенном тексте. Этот способ "устранения" части кода бывает удобен при отладке.

    Очень удобна новая возможность редактора показывать соответствующие пары скобок (см. рисунок).

    [ К содержанию ]

    Сворачивание части кода

    Как и в Delphi8, в редакторе Delphi2005 реализовано частичное скрытие (сворачивание кода). Это позволяет работать с большими текстами, не прокручивая многостраничный экран. Достаточно оставить развернутым сейчас только тот код, который используется. Для того чтобы свернуть или развернуть нужный блок, специально предусмотрены значки [-] и [+] в левой части редактора. Если нажать на значок [-], например, возле определения метода, код этого метода будет свернут, то есть, убран из видимости. Но, кроме этого, есть возможность применить эту операцию ко всему коду, а не только к текущему месту.

    В меню по правой кнопке мыши есть два пункта Fold и UnFold. Это, соответственно, операции "свернуть" и "развернуть". Для каждой из них нужно указать место действия. Например, свернуть все методы в коде или все определения типов. Хочется заметить, что "свернутая" часть кода никуда не девается, а лишь уходит из видимой части редактора. Так что, если при компиляции или во время работы "Error Insight", ошибка окажется в свернутом коде, он прекрасным образом будет развернут автоматически в нужном месте. Так что никакой путаницы не возникнет.

    Кроме этих возможностей, введены две директивы, которые по синтаксису аналогичны директивам компилятора, но оказывают влияние на поведение редактора, а не на генерируемый код. Это директивы $REGION и $ENDREGION. Они задают начало и конец сворачиваемого региона кода. Можно задать имя региона, в этом случае, когда регион свернут, вместо многоточия отображается имя региона (см. рис).

    [ К содержанию ]

    Help Insight

    Если в привычном "Code Insight" показывался тип идентификатора (переменной, функции и т.д.) и модуль, в котором он определен, то "Help Insight" представляет собой всплывающее окно-подсказку, с кратким описанием этого идентификатора и дополнительными ссылками (см. рис). Достаточно подвести мышку к нужному идентификатору, чтобы получить такой "маленький help". Использовать "Help Insight" можно в комбинации с "Code Completion". Если в окне "Code Completion" выбрать определенное свойство или метод, то справа появится окно с подсказкой.

    Открыть скриншот в отдельном окне

    Эта возможность реализована не только для стандартных, но и для собственных классов и переменных. Использование "Help Insight" включено по умолчанию. Местонахождение в настройках: Tools->Options->Editor Options->Code Insight

    [ К содержанию ]

    Error Insight

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

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

    [ К содержанию ]

    Sync Edit

    При выделении части кода в редакторе, на левой полосе, вслед за выделяемыми строками, передвигается маленькая иконка (на рисунке она отмечена красным). Это включение режима "Sync Edit". Если нажать на эту иконку, то выделенный текст подкрасится (при цветовых настройках по умолчанию) голубым цветом и будет выделен первый в блоке идентификатор.

    Открыть скриншот в отдельном окне

    Суть режима "Sync Edit" в том, что он позволяет показать в выделенном тексте все повторяющиеся идентификаторы, их может оказаться несколько групп. Самая первая считается текущей.

    Для текущей группы все дубли помечены рамочкой, для остальных групп просто подчеркнуты. Переход между группами повторяющихся идентификаторов осуществляется клавишей TAB. Если начать изменять текущий идентификатор, то вслед за ним будут синхронно изменены все его дубли в этом выделенном блоке. Это похоже на "Рефакторинг: переименование идентификатора".

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

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

    Повторное нажатие на иконку на левой полосе редактора кода, выключает "Sync Edit" и возвращает обычный режим редактирования.

    [ К содержанию ]

    История изменений

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

    Открыть скриншот в отдельном окне

    После даже этой небольшой работы с новой IDE, возвращение к старым версиям в свои рабочие проекты кажется откатом назад.

    [ К содержанию ]

    Но, есть и неприятные моменты.

    Русские буквы в комментариях к коду

    Поначалу неприятно удивило открытие файлов кода с комментариями в заголовке, написанными русскими буквами в кодировке Win1251. Часть таких файлов открываются, как двоичные. После небольшого исследования оказалось, что портит все маленькая буква "я" в тексте комментариев в начале модуля. Если в новой среде написать такой комментарий в начале модуля, то он редактируется нормально. Но, если его закрыть, то вновь откроется он в двоичном виде. По-видимому, проблема связана с тем, что редактор кода по первой порции фиксированного объема определяет формат файла. Встречая в этой порции букву "я" (ее код $FF), редактор некорректно определяет формат файла. При переносе текста с буквой "я" в конец файла или в середину файла большого размера, его формат определяется корректно.

    Сходная ситуация обсуждалась в Подводных камнях.

    Проблема с открытием таких файлов решается или удалением слов из заголовка модуля, содержащих маленькую букву "я", или замена ее на букву "Я" в верхнем регистре. Кому что нравится.

    Русские буквы в названиях каталогов проекта

    Проекты VCL.NET и WinForms не запускаются из-под среды, если в полном имени каталога проекта есть русские буквы. Среда сообщает "Unable to create process".

    К сожалению, ссылки в окне "Help Insight" не будут работать, если у вас в названии каталогов используются русские буквы.

    [ К содержанию ]

    Рефакторинг

    Рефакторинг "переименование символа" — при позиционировании курсора на нужном идентификаторе и выборе пункта меню Refactoring | Rename Field, среда показывает все строки, где встречается выбранный идентификатор, и предлагает выбрать новое имя. Очень удобная возможность, как тут не вспомнить Мартина Фаулера:

    "Важной частью пропагандируемого мною стиля программирования является разложение сложных процедур на небольшие методы. Если делать это неправильно, то придется изрядно помучиться, выясняя, что же делают эти маленькие методы. Избежать таких мучений помогает назначение методам хороших имен. Методам следует давать имена, раскрывающие их назначение. Хороший способ для этого - представить себе, каким должен быть комментарий к методу, и преобразовать этот комментарий в имя метода. Жизнь такова, что удачное имя может не сразу придти в голову. В подобной ситуации может возникнуть соблазн бросить это занятие - в конце концов, не в имени счастье. Это вас соблазняет бес, не слушайте его. Если вы видите, что у метода плохое имя, обязательно измените его. Помните, что ваш код в первую очередь предназначен человеку, а только потом - компьютеру. Человеку нужны хорошие имена. Вспомните, сколько времени вы потратили, пытаясь что-то сделать, и насколько проще было бы, окажись у пары методов более удачные имена. Создание хороших имен - это мастерство, требующее практики; совершенствование этого мастерства - ключ к превращению в действительно искусного программиста. То же справедливо и в отношении других элементов сигнатуры метода. Если переупорядочивание параметров проясняет суть - выполните его."

    Раньше для подобных действий использовался метод переименования идентификатора в месте, где он объявлен, и инкрементная компиляция до выяснения всех мест, в которых этот идентификатор использовался.

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

    Рефакторинг: процесс выделения метода

    После выделения метода

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

    [ К содержанию ]

    Unit-тестирование

    "Мой опыт показывает, что создав хорошие тесты, можно значительно увеличить скорость программирования"
    (с) Мартин Фаулер.

    Delphi 2005 располагает встроенными средствами для организации тестирования работы отдельных модулей программы, основанными на известных open-source проектах DUnit и NUnit (.NET). Среда позволяет создать проект-оболочку для тестов и шаблоны тестирующих модулей. Рассмотрим возможности Delphi 2005 на примере тестирования простого класса, осуществляющего перевод чисел из двоичной формы в символьную по заданному основанию системы счисления и, наоборот, из символьной в двоичную.

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

    Реализация метода ToString будет содержать ошибки, которые мы будем обнаруживать тестированием. Первая реализация выглядит так:

    unit Convertor;
    
    interface
    
    type
      TNumericConvertor = class
      private
        FBase: Integer;
      public
        constructor Create (const ABase: Integer);
        property Base: Integer read FBase;
        function ToString (const Value: Integer): string;
        function ToNumber (const Value: string): Integer;
      end;
    
    implementation
    
    { TNumericConvertor }
    
    constructor TNumericConvertor.Create(const ABase: Integer);
    begin
      Assert ((ABase > 1) and (ABase <= 36), 'Illegal Base specfied');
      FBase := ABase;
    end;
    
    function TNumericConvertor.ToNumber(const Value: string): Integer;
    var
      I, Digit: Integer;
    begin
      Result := 0;
      for I:=1 to Length(Value) do begin
        if Value[I] > '9' then
          Digit := Ord(Value[I]) - Ord('A') + 10
        else
          Digit := Ord(Value[I]) - Ord('0');
        Assert ((Digit >= 0) and (Digit < Fbase), 'Illegal character');
        Result := Result * FBase + Digit;
      end;
    end;
    
    function TNumericConvertor.ToString(const Value: Integer): string;
    var
      Rem, Quot: Integer;
    begin
      Assert (Value >= 0, 'Only positive numbers can be converted');
      Result := '';
      Quot := Value;
      while Quot <> 0 do begin
        Rem := Quot mod FBase;
        if Rem >= 10 then
          Result := Result + Char(Rem + Ord('0'))
        else
          Result := Result + Char(Rem + Ord('A') - 10);
        Quot := Quot div Fbase;
      end;
      if Result = '' then
        Result := '0';
    end;
    
    end.
    

    Создадим проект-оболочку для тестов командой File|New|Other выбрав в категории Unit Tests элемент Test Project (см. рис. 1 и 1-1).

    Показать скриншоты в отдельном окне: рисунок 1 и рисунок 1-1

    После этого группа проектов принимает вид:

    Добавим в эту оболочку первый тестирующий модуль командой File|New|Other выбрав в категории Unit Tests элемент Test Case.

    Показать скриншоты в отдельном окне:

    В результате этих действий в IDE открывается окно с кодом сгенерированного класса для тестирования методов выбранного класса.

    unit TestConvertor;
    {
    
      Delphi DUnit Test Case
      ----------------------
      This unit contains a skeleton test case class generated by the
      Test Case Wizard.
      Modify the generated code to correctly setup and call the methods
      from the unit being tested.
    
    }
    
    interface
    
    uses
      TestFramework, Convertor;
    type
      // Test methods for class TNumericConvertor
      TestTNumericConvertor = class(TTestCase)
      strict private
        FNumericConvertor: TNumericConvertor;
      public
        procedure SetUp; override;
        procedure TearDown; override;
      published
        procedure TestToString;
        procedure TestToNumber;
      end;
    
    implementation
    
    procedure TestTNumericConvertor.SetUp;
    begin
      FNumericConvertor := TNumericConvertor.Create;
    end;
    
    procedure TestTNumericConvertor.TearDown;
    begin
      FNumericConvertor.Free;
      FNumericConvertor := nil;
    end;
    
    procedure TestTNumericConvertor.TestToString;
    var
      ReturnValue: string;
      Value: Integer;
    begin
      // TODO: Setup method call parameters
      ReturnValue := FNumericConvertor.ToString(Value);
      // TODO: Validate method results
    end;
    
    procedure TestTNumericConvertor.TestToNumber;
    var
      ReturnValue: Integer;
      Value: string;
    begin
      // TODO: Setup method call parameters
      ReturnValue := FNumericConvertor.ToNumber(Value);
      // TODO: Validate method results
    end;
    
    initialization
      // Register any test cases with the test runner
      RegisterTest(TestTNumericConvertor.Suite);
    end.
    

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

    В методе Setup пишем код для вызова корректного конструктора

    procedure TestTNumericConvertor.SetUp;
    begin
      FNumericConvertor := TNumericConvertor.Create (10);
    end;
    

    Метод TestToString принимает вид:

    procedure TestTNumericConvertor.TestToString;
    var
      ReturnValue: string;
      Value: Integer;
    begin
      Value := 10;
      ReturnValue := FNumericConvertor.ToString(Value);
      Assert (ReturnValue = '10', 'Expect ''10'',
                   receive '''+ReturnValue+'''');
    end;
    

    И последний метод - TestToNumber

    procedure TestTNumericConvertor.TestToNumber;
    var
      ReturnValue: Integer;
      Value: string;
    begin
      Value := '10';
      ReturnValue := FNumericConvertor.ToNumber(Value);
      Assert (Returnvalue = 10, 'Expect 10,
              receive '+IntToStr(ReturnValue));
    end;
    

    Компилируем и запускаем тестовый проект, его окно выглядит так.

    После запуска тестов видно, что один из методов исходного класса работает некорректно, так как полученный результат не соответствует ожидаемому (Ожидается '10' получен 'AB')

    Показать скриншот в отдельном окне

    Анализируя исходный код метода, видно, что при переводе очередного знака числа, условия then и else необходимо поменять местами:

    if Rem >= 10 then
          Result := Result + Char(Rem + Ord('A') - 10)
        else
          Result := Result + Char(Rem + Ord('0'));
    

    Перекомпилировав проект после исправления, снова запускаем тесты.

    Видно, что ошибка исправлена, но метод все работает не так, как ожидается (Ожидается '10', получено '01').

    Показать скриншот в отдельном окне

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

    if Rem >= 10 then
          Result := Char(Rem + Ord('A') - 10) + Result
        else
          Result := Char(Rem + Ord('0')) + Result;
    

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

    Показать скриншот в отдельном окне

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

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

    unit TestConvertor1;
    {
    
     Delphi DUnit Test Case
     ----------------------
     This unit contains a skeleton test case
     class generated by the Test Case Wizard
     Modify the generated code to correctly
     setup and call the methods from the unit
     being tested.
    
    }
    
    interface
    
    uses
      TestFramework, Convertor;
    type
      // Test methods for class TNumericConvertor
      TestTNumericConvertor1 = class(TTestCase)
      strict private
        FNumericConvertor: TNumericConvertor;
      public
        procedure SetUp; override;
        procedure TearDown; override;
      published
        procedure TestToString;
        procedure TestToNumber;
      end;
    
    implementation
    uses
      SysUtils;
    
    procedure TestTNumericConvertor1.SetUp;
    begin
      FNumericConvertor := TNumericConvertor.Create(2);
    end;
    
    procedure TestTNumericConvertor1.TearDown;
    begin
      FNumericConvertor.Free;
      FNumericConvertor := nil;
    end;
    
    procedure TestTNumericConvertor1.TestToString;
    var
      ReturnValue: string;
      Value: Integer;
    begin
      Value := 11;
      ReturnValue := FNumericConvertor.ToString(Value);
      Assert(ReturnValue = '1011', 'Expect ''1011'',
             receive '''+ReturnValue+'''');
    end;
    
    procedure TestTNumericConvertor1.TestToNumber;
    var
      ReturnValue: Integer;
      Value: string;
    begin
      Value := '1011';
      ReturnValue := FNumericConvertor.ToNumber(Value);
      Assert(ReturnValue = 11, 'Expect 11,
             receive '+IntToStr(ReturnValue));
    end;
    
    initialization
      // Register any test cases with the test runner
      RegisterTest(TestTNumericConvertor1.Suite);
    end.
    

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

    Показать скриншот в отдельном окне

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

    Спасибо фирме Borland, что такие нужны и удобные средства уже встроены в их новый продукт — Delphi 2005.

    [ К содержанию ]

    Компилятор

    Предопределенный символ для идентификации компилятора - VER170 (выяснено опытным путем, в Help информация отсутствует).

    Многие из перечисленных ниже возможностей являются нововведениями только для компилятора Win32.

    for..in..do

    В язык Delphi добавлена конструкция for..in..do для перебора всех членов массива, строки, множества или коллекции.

    • for Element in ArrayExpr do Stmt;
    • for Element in StringExpr do Stmt;
    • for Element in SetExpr do Stmt;
    • for Element in CollectionExpr do Stmt;

    То есть, в цикле перебираются все элементы некоего множества и для каждого выполняется тело цикла. Например, теперь ничего не стоит перевернуть строку наоборот (см. рис)

    Полная и весьма понятная информация находится в справке, смотрите раздел "Declarations and Statements"

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

    • содержать public метод экземпляра с именем GetEnumerator, который должен возвращать экземпляр класса, ссылку на интерфейс или запись (record).
    • экземпляр класса, ссылка на интерфейс или запись, возвращенные методом GetEnumerator, должны содержать public метод экземпляра с именем MoveNext, возвращающий значение типа boolean.
    • экземпляр класса, ссылка на интерфейс или запись, возвращенные методом GetEnumerator должны содержать public свойство экземпляра с именем Current, тип которого должен соответствовать типу элементов контейнера.

    Экземпляр, возвращенный методом GetEnumerator, автоматически разрушается после окончания цикла for..in.

    Следующий пример показывает реализацию паттерна коллекции

    program Project1;
    
    {$APPTYPE CONSOLE}
    
    type
      TMyIntArray = array of Integer;
    
      TMyEnumerator = class
        Values: TMyIntArray;
        Index:  Integer;
      public
        constructor Create;
        function GetCurrent: Integer;
        function MoveNext:   Boolean;
        property Current:    Integer read GetCurrent;
      end;
    
      TMyContainer = class
      public
       function GetEnumerator: TMyEnumerator;
      end;
    
    constructor TMyEnumerator.Create;
    begin
      inherited Create;
      Values := TMyIntArray.Create(100, 200, 300);
      Index := -1;
    end;
    
    function TMyEnumerator.MoveNext: Boolean;
    begin
      if Index < High(Values) then
        begin
          Inc(Index);
          Result := True;
        end
      else
        Result := False;
    end;
    
    function TMyEnumerator.GetCurrent: Integer;
    begin
      Result := Values[Index];
    end;
    
    function TMyContainer.GetEnumerator: TMyEnumerator;
    begin
      Result := TMyEnumerator.Create;
    end;
    
    var
      MyContainer: TMyContainer;
      I: Integer;
    
      Counter: Integer;
      ar: TMyIntArray;
    
    begin
      MyContainer := TMyContainer.Create;
    
      Counter := 0;
      for I in MyContainer do
        Inc(Counter, I);
      WriteLn('Counter = ', Counter);
    end.
    

    Поддержка синтаксиса for...in уже встроена в ряд классов VCL, например, TList, TComponent, TCollection, и т.д. - в общей сложности около 15 классов. Так, например, перечисление имен компонентов формы может выглядеть следующим образом (хотя и непривычно):

    var
      I: TComponent;
    begin
      for I in Self do
        ListBox.Add (I.Name);
    end;
    

    [ К содержанию ]

    Модификаторы области видимости

    Для большей совместимости исходного кода с Delphi for .NET введены два новых модификатора области видимости членов класса.

    strict private

    Члены класса с видимостью strict private доступны только самому классу.

    strict protected

    Члены класса с видимостью strict protected доступны только самому классу и его непосредственным наследникам.

    Отличие новых модификаторов от традиционных private и protected заключается в том, что члены с новыми модификаторами не доступны постороннему коду, находящемуся в том же модуле.

    Class property

    Раньше, хотя компилятор и позволял использовать методы класса в качестве аксессоров свойств, обращение к таким свойствам в форме TSomeClass.PropName было невозможно. Теперь, с введением свойств класса такое обращение разрешено. Однако, в отличие от Delphi for .NET, свойства класса могут работать только через методы, т.к. понятие полей класса для компилятора Delphi for Win32 отсутствует.

    type
      TTestClass = class
        class function GetClassProp: integer;
        class procedure SetClassProp(value: integer);
        class property ClassProp: integer read
                       GetClassProp write SetClassProp;
      end;
    
    TestClass.ClassProp := ...;
    

    [ К содержанию ]

    Вложенные типы данных и константы

    Эта возможность также является новшеством только для компилятора Delphi for Win32. Теперь, как и в случае с Delphi for .NET, можно объявлять типы данных и константы внутри других классов.

    type
      TOuterClass = class
       public
          const
             x = 12;
             i: integer = 1;
          type
             TInnerClass = class
             public
                myInnerField: Integer;
                procedure innerProc;
             end;
    
         procedure outerProc;
       end;
    

    Обращение ко вложенным типам и константам производится через имя типа, в который они вложены, например, TOuterClass.TInnerClass или TOuterClass.x. Для вложенных типов и констант действуют те же модификаторы видимости, что и для остальных членов классов.

    Существует одна интересная особенность. Хотя компилятор для Win32 не поддерживает полей класса, их в какой-то мере можно заменить вложенными типизированными константами при условии, что включена опция компилятора $J (она же $WRITEABLECONST).

    [ К содержанию ]

    Ненаследуемые классы

    Если по каким-то причинам разработчик хочет запретить создание наследников класса, это можно сделать используя модификатор sealed.

    type
      TMyFinalClass = class sealed(TObject)
    
      end;
    

    Так же, в язык добавлено ключевое слово final для вирутальных и динамических методов, запрещающее их дальнейшее перекрытие. Эта возможность присутствует как в компиляторе .NET, так и в компиляторе для Win32

    Например, компиляция кода

    type
      TClass1 = class
      private
      ....
      public
        constructor Create;
        destructor Destroy; override; final;
    ....
    end;
    
    TClass2 = class(TClass1)
    ....
     public
        destructor Destroy; override;
    end;
    

    приведет к ошибке - E2352 Cannot override a final method.

    [ К содержанию ]

    XML Documentation

    Для компилятора Delphi for .NET эта возможность существует с версии Delphi 8. Теперь эта возможность доступна и в компиляторе для Win32. Компилятор умеет различать в исходном тексте специальным образом оформленные комментарии и генерировать на их основе XML файлы. Формат комментариев во многом похож на XML. Каждый комментарий, который будет анализироваться на наличие тегов XML документации предшествовует документируемому объекту и должен начинаться с комбинации из трёх символов "/". Существует набор тегов, которые рекомендуется применять при оформлении комментариев. Он описан в справке .NET SDK. К сожалению для тех, кто не любит писать всякие теги руками, IDE никак не облегчает оформление таких комментариев.

    Примитивный пример оформления документации:

    type
      ///<summary> Test comment
      ///</summary>
      TForm3 = class(TForm)
      private
        { Private declarations }
        ///<summary> Test comment 1
        ///</summary>
        procedure Test;
      public
        { Public declarations }
      end;
    

    Примерный вид XML документации, генерируемой компилятором:

    <?xml version="1.0" encoding="utf-8"?>
    <namespace name="Unit3">
      <class name="TForm3">
        <devnotes>
          <summary> Test comment
          </summary>
        </devnotes>
        <ancestor name="TForm" namespace="Forms">
          <methodref name="ArrangeIcons" visibility="public" />
          <methodref name="Cascade" visibility="public" />
    
          здесь перечисляются предки и все их члены
    
        </ancestor>
        <members>
          <procedure name="Test" visibility="private">
            <devnotes>
              <summary> Test comment 1
              </summary>
            </devnotes>
          </procedure>
        </members>
      </class>
      <variable name="Form3" type="TForm3" />
    </namespace>
    

    [ К содержанию ]

    Inline

    В новой версии компилятора Delphi появилась возможность использования inline кода. Для этого наполнена новым смыслом директива inline. Теперь, если процедура или функция имеют директиву inline, это заставит компилятор попытаться вставить в место, где эта процедура используется, не вызов, а код тела процедуры. Само наличие директивы inline ещё не гарантирует того, что попытка будет удачной. Существуют определенные ограничения. Согласно справочной системе, эти ограничения таковы:

    • inline не работает для любых видов методов позднего связывания (virtual, dynamic, message)
    • inline не работает для процедур содержащих код на языке ассемблера,
    • inline не работает для конструкторов и деструкторов
    • inline не работает для главного блока программы и секций инициализации и финализации модулей
    • inline код может быть использован внутри пакетов, но inline не работает через границы пакетов
    • inline не работает в модулях, связанных кольцевой зависимостью. Это ограничение включает и неявные кольцевые ссылки между модулями. Например, если модуль A использует модуль B, модуль B использует C, а C, в свою очередь, использует A, то при компиляции модуля A не будет производиться inline-подстановка кода из модулей B и C.
    • inline-подстановка в модулях, входящих в кольцевые зависимости, может быть произведена, если подстановка производится из модуля, не входящего в кольцо зависимостей. Например, если в предыдущем примере модуль A использует также модуль D, то в модуле A возможна inline-подстановка кода из модуля D.
    • inline не работает, если процедура объявлена в секции interface модуля и обращается к символам, объявленным в секции implementation.
    • inline не работает для методов в классах, если они обращаются к членам классов, имеющим более низкую видимость, чем сам метод. Например, если public метод обращается к private методу, то для такого метода inline-подстановка осуществляться не будет.
    • если процедура, помеченная как inline использует процедуры или переменные из внешних модулей, то все эти модули должны быть перечислены в списке uses того модуля, где inline процедура будет использована, иначе inline-подстановка не производится.
    • inline-подстановка не осуществляется для процедур и функций, которые используются в выражениях проверки условия циклов while и repeat.

    При использовании inline процедур следует помнить о том, что изменение кода такой процедуры приведет к перекомпиляции всех модулей, где она используется.

    Также для контроля использования inline-подстановок введена директива компилятора {$INLINE}. Она может принимать следующие значения:

    • {$INLINE ON} - Процедуры, с директивой inline будут помечены, как процедуры, для которых возможна inline-подстановка. При вызове таких процедур будет сделана попытка inline подстановки кода. Действует по умолчанию.
    • {$INLINE AUTO} - Процедуры, с директивой inline будут помечены, как процедуры, для которых возможна inline-подстановка только в том случае, если код процедуры будет размером меньше 32 байт.
    • {$INLINE OFF} - Процедуры, не смотря на наличие директивы inline, никогда не будут помечены, как процедуры, для которых возможна inline-подстановка. При вызове процедур попытка inline подстановки кода не будет сделана.
    Unsafe Code

    Для компилятора Delphi for .NET добавлена возможность включения небезопасного кода в приложения .NET. Для этого введена локальная директива компилятора {$UNSAFECODE}, которая может принимать значения ON и OFF а также добавлено ключевое слово unsafe, которое применяется к процедурам и функциям. Приложения, использующие небезопасный код не проходит проверку при помощи утилиты PEVerify. Подробнее о небезопасном коде смотрите в документации .NET SDK.

    procedure unsafeProc; unsafe;
    begin
    end;
    

    [ К содержанию ]

    Unicode-идентификаторы

    Появилась возможность использовать в именах типов и переменных символы Unicode.

    Запись вида

    type
      Работник = record
        Фамилия: string;
        Имя: string;
        Отчество: string;
        ДатаРождения: TdateTime;
        Должность: string;
      end;
    

    выглядит понятнее, чем

    Rabotnik = record
       Familija: string;
       Imya: string;
       Ochestvo: string;
       DataRogdenija: TdateTime;
       Dolgjnost: string;
     end;
    

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

    Пример компилирующегося и работающего кода:

    type
      Целое = Integer;
    
    procedure TfMain.BtnCountClick(Sender: TObject);
    var
      Счетчик: Целое;
    begin
      for Счетчик:=0 to 5 do begin
        btnCount.Caption := IntToStr(Счетчик);
        Sleep(500);
        Application.ProcessMessages;
      end;
    end;
    

    [ К содержанию ]

    Расширенный синтаксис объявления и инициализации массивов

    Delphi для Win32

    Теперь можно делать задание размеров массива и инициализацию одной строкой

    type
      TMyIntArray = array of Integer;
    
    var
      Ints: TMyIntArray;
    
    begin
      Ints := TMyIntArray.Create(1,2,3,4,5);
    

    Delphi for .NET

    Новый расширенный синтаксис позволяет объявлять массивы в форме

    array[, ..., ] of baseType;

    Также возможна инициализация массивов при помощи стандартной процедуры new.

    var
      a: array [,,] of integer;  // 3 dimensional array
      b: array [,] of integer;   // 2 dimensional array
      c: array [,] of TPoint;    // 2 dimensional array of TPoint
    
    begin
      // New taking element type and size of each dimension.
      a := New(array[3,5,7] of integer);
      // New taking the element type and initializer list.
      b := New(array[,] of integer, ((1,2,3), (4,5,6)));
      // New taking an initializer list of TPoint.
      c := New(array[,] of TPoint, (((X:1;Y:2), (X:3;Y:4)),
                                   ((X:5;Y:6), (X:7;Y:8))));
    end.
    

    [ К содержанию ]

    Отладка

    Понравилось поведение системы при возникновении Exception — появляется окно с уведомлением об Exception и с возможностью поставить галочку "Игнорировать этот тип Exception", вместо того, чтобы открывать окно Tools | Debugger..

    Изменилась работа с точками останова. Появилась очень удобная возможность, не удаляя точку останова, отключить ее, пометив как "disable". Это можно сделать в редакторе кода по правой кнопке на точке останова, и прямо в списке "Breakpoint list". В этом списке можно включать/выключать все точки или определенные группы (меню по правой кнопке). Так же, теперь прямо в окне "Breakpoint list" можно изменять значение Condition и принадлежность к определенной группе для каждой точки.

    [ К содержанию ]

    Встроенный Data Explorer

    В IDE интегрирован Data Explorer, который содержит как средства просмотра базы данных, так и ряд инструментов для редактирования. Окно Data Explorer можно найти на одной из закладок окна Project Manager справа от редактора кода (при умолчанных настройках среды) или в меню View | Data Explorer

    Выбираете провайдера для вашей БД, настраиваете коннекцию к базе и получаете список ее объектов:

    [ К содержанию ]

    Таблицы

    Для таблиц определены следующие операции:

    Просмотр данных

    Это операция по умолчанию — двойной клик по имени таблицы в списке. Открывается отдельное окно с содержимым таблицы. Возможно редактировать все поля, даже identity и computed column. Диагностика производится в момент сохранения изменений (правая кнопка мыши | Update/Rollback), так что испортить таблицу затруднительно.

    Изменение структуры

    Визуальный аналог команды "Alter table".

    В этом окне по правой кнопке мыши доступны команды Save changes/Show DDL/ Exeсute DDL

    DDL (Data definition language) — текст SQL-скрипта, который отражает сделанные визуально изменения в структуре таблицы.

    Удаление таблицы

    Выполнение команды "Drop table"

    Копирование таблицы

    Копирование существующей таблицы в новую. Происходит, как создание новой таблицы с такой же структурой (имя новой таблицы запрашивается при выполнении paste) и заполнении ее данным из копируемой таблицы.

    [ К содержанию ]

    Хранимые процедуры

    Доступные операции Refresh/View Parameters. Окно просмотра параметров открывается при двойном клике на имени процедуры. В этом окне можно указать значения всех входных параметров и, выполнив процедуру, получить заполненные значениями выходные параметры (см. рис). Для выполнения процедуры можно воспользоваться иконкой в верхнем левом углу окна или по правой кнопке мыши (команда Execute).

    Если хранимая процедура в качестве результата возвращает еще и (или только) набор данных, необходимо поставить галочку "Stored procedure has one or more cursors" и выполнить процедуру снова.

    Просмотр скриншотов в отдельном окне:

    Окно просмотра параметров

    Окно с настройкой параметров процедуры и получением результатов

    Результат работы хранимой процедуры, которая возвращает набор данных

    Безусловно, новые возможности для тестирования работы хранимых процедур очень удобны и позволят упростить жизнь разработчика баз данных.

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

    [ К содержанию ]

    SQL Window

    Это привычное окно для выполнения SQL-запросов. Так как тестирование проходило только для MS SQL Server, то возможно, некоторые странности связаны с конкретным драйвером.

    Сами SQL-запросы любой сложности (UNION, вложенные подзапросы и т.п.) выполняются без проблем. Странности начались после попытки исполнить в этом окне процедуру ("execute имя_процедуры"), которая в качестве результата возвращает набор данных. В качестве результата было получено сообщение "-1 row(s) affected". И этот результат был одинаков для всех процедур одного сервера. Тест на другом сервере дал иной результат, возможно этот эффект зависит от настроек на сервере (или от настроек конкретной базы), но такого иследования не проводилось. Итак, на другом сервере после выполнения процедуры было получено окошко с сообщением, например, таким: "192 row(s) affected", что само по себе верно, но никакого результата, то есть набора данных, все равно не было выведено. Если в тексте процедуры был оператор "Insert Into имя_таблицы exec имя_процедуры", то в качестве nколичества обработанных строк в результирующем сообщении выдавалось количество строк этого insert'а, а вовсе не nпоследнего select'а процедуры.

    Можно предположить, что проблема кроется в ADO.NET, на котором реализован Data Explorer.

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

    * * *

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

    Спасибо компании Borland за возможность ознакомиться с новой версией, которая несомненно, позволит вывести разработку приложений на качественно новый этап.

    К материалу прилагаются файлы:
    Пример для раздела "Unit-тестирование" (565.5 K)


     


    ХАЙВЕЙ - лучший российский хостинг-провайдер: хостинг, регистрация доменов, услуга Ваша@почта, поддержка 24 часа


    NetPromoter - единственный российский профессиональный комплекс программ и сервисов для раскрутки сайта и интернет-статистики


    STSS - известный поставщик надежных серверных решений различного назначения на платформе Intel (Xeon) и AMD.


    5-55: the ITIL company. Практический опыт и теоретические знания на лучших семинарах по ITIL и процессам ITSM.


    Подписка на новости IT-портала CITForum.ru
    (библиотека, ftp-архив CITKIT.ru)

    Новые поступления в on-line библиотеку:

    28 апреля

  • Выбор первого дистрибутива Linux: Пособие для начинающих
  • Обфускация и защита программных продуктов
  • Анализ и оптимизация циклов с помощью производящих функций
  • Стратегии объектно-реляционного отображения: систематизация и анализ на основе паттернов

    26 апреля

  • Business Intelligence обещает значительный рост в 2005 году
  • Десять основных тенденций 2005 года в области Business Intelligence и Хранилищ данных
  • Управление эффективностью бизнеса и предсказуемость
  • Увеличение эффективности бизнеса: пять ошибок управления, которых следует избегать
  • Потребность в организационных данных: модель комплексного управления эффективностью бизнеса
  • Технология Хранилищ данных для государственных учреждений
  • Оцените, насколько совершенно ваше Хранилище данных

    21 апреля

  • Исполнение моделей при помощи виртуальной машины
  • Параллельные алгоритмы компьютерной алгебры
  • От стандарта до стандарта (о стандартизации оптических разъемов)
  • За штурвалом IP-станции

    Продолжение дискуссии читателей:

  • Линукс и пользователи, или что мне не нравится в Linux
  • Еще один взгляд на альтернативные ОС (и софт для них)
  • О некомпетентности пользователя Windows
  • Переписка Долгачева В.С. и Монахова В.В.

    19 апреля

  • Межпротокольный шлюз NAT-PT с функциями DNS-ALG и FTP-ALG для обеспечения взаимодействия между сетями IPv4 и IPv6
  • Рефакторинг архитектуры программного обеспечения: выделение слоев
  • Комбинаторика слов и построение тестовых последовательностей
  • Функциональное тестирование Web-приложений на основе технологии UniTesK

    14 апреля

  • Как организовать двойную парольную защиту данных в Oracle
  • Деревянный интерфейс

    Продолжение дискуссии читателей:

  • Microsoft против мира
  • Впечатления от прочитанного

    12 апреля

  • Крупные проблемы и текущие задачи исследований в области баз данных
  • Глава 2 из книги Т.Кайта "Oracle для профессионалов"Архитектура

    Дискуссия читателей о Linux и Windows:

  • Деньги правят миром, и у кого их больше, тот и прав!
  • О злокозненности некомпетентных пользователей, или почему я не люблю ограниченных пользователей Windows

    7 апреля

  • О доблести Билла Гейтса, или почему Windows лучше, чем LINUX или Mac OS
  • Витая пара - все ли так просто?!
  • Выбираем сервер печати
  • Один слой хорошо, а два - лучше (о пишущих DVD-приводах)

    5 апреля

  • Использование Caché SQL Gateway
  • Глава 19 из книги Т.Кайта "Oracle для профессионалов"Хранимые процедуры на языке Java
  • Что такое PostgreSQL?
  • Обновлен PostgreSQL FAQ

    31 марта

  • Использование Веб-сервисов в Caché
  • Защита на уровне строк (Oracle)
  • Секции в реальном мире

    29 марта

  • Разработка успешных приложений для Oracle - первая глава из книги Тома Кайта "Oracle для профессионалов"
  • Web-сервисы: растущие опасения (мнение аналитиков IDC)
  • Технология OLAP - мощная альтернатива электронным таблицам
  • Какой модной стала подготовка отчетности

    24 марта

  • Многоверсионность данных и управление параллельными транзакциями
  • Исключение из правил. Опыт разработки и внедрения финансовой корпоративной системы
  • Обнаружение компрометаций ядра Linux с помощью gdb
  • Корпоративная сервисная шина - "бюджетный" подход к решению задач интеграции
  • Сервис-ориентированная архитектура
  • Бизнес-процессы и XML

    22 марта

  • Доступно. И точка! (обзор точек беспроводного доступа)
  • Коммутаторы Fast/Gigabit Ethernet для "большой" сети
  • Push to Talk: нажми на кнопку и ...говори
  • Сети нового поколения и технология softswitch

    17 марта

  • Часто задаваемые вопросы о proxy (proxy FAQ)
  • Самонастраивающаяся база данных: управляемые приложения и настройка SQL
  • Еще раз о волоконных трассах
  • Настраиваем русский Unicode в FreeBSD-5.3.

    10 марта

  • Еще не сказанное о волоконной оптике
  • Wi-Fi на службе оператора
  • Пора менять платформу?
    (о сокетах LGA775 и PGA478)

    Oracle:

  • Детальный аудит для практических целей
  • Шифруем свои ресурсы данных

    3 марта

  • Требования к проекту. Классификация - первый шаг к пониманию
  • Gtk vs. Qt: драки не будет
  • Управление бизнесом "по максимуму": BPM для финансовых учреждений
  • Реализация решения по управлению эффективностью бизнеса
  • Новые SerialATA-винчестеры
  • Карман для сервера

    1 марта

  • Выбрать корпус - нет ничего проще?
  • Создание виртуальной сети с удаленной загрузкой узлов
  • Текущее состояние и перспективы развития рынка интеграционных технологий
  • Интеграция корпоративной информации: новое направление
  • Архитектурные подходы к консолидации

    24 февраля

  • Каждому проекту своя методология
  • Императив интеграции
  • Безопасность IP-телефонии - полевые зарисовки
  • О злокозненности Билла Гейтса, или почему я не люблю Windows

    22 февраля

  • Oracle10: шифруем данные
  • В версии Oracle10 "виртуальные частные базы данных" данных стали избирательнее
  • Каждому (пользователю) свое (данное в таблице)
    Часть 1
    Часть 2
  • Ускоряем интернет
  • Сетевая аутентификация на практике
  • В фокусе Microsoft Virtual Server 2005

    17 февраля

    Открыт новый раздел
    Все об Open Source

    Все новости >>>



  • IT-консалтинг Software Engineering Программирование Open Source СУБД Безопасность Internet Сети Операционные системы Hardware

    Информация для рекламодателей PR-акции, размещение рекламы - pr@citforum.ru, тел. +7 095 4119920 Пресс-релизы - manager@citforum.ru
    Послать комментарий
    Информация для авторов
    Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
    Copyright © 1997-2000 CIT, © 2001-2004 CIT Forum
    Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...