home Преподавание Информационных Технологий в России
Открытая всероссийская конференция

АПКИТ
Конференция

Информационное сообщение

Место проведения

Программа конференции

Участники

Фоторепортаж

Программный комитет

Программный комитет

Спонсоры
Информ. спонсоры
Орг. поддержка

ЛАНИТ-ТЕРКОМ

Нижегородский госуниверситет им. Н.И. Лобачевского

ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ, ЯЗЫК C# И НЕКОТОРЫЕ ПРОБЛЕМЫ

Биллиг Владимир Арнольдович (Vladimir.Billig@tversu.ru)
Тверской государственный университет

Аннотация
ООП де факто стало основной технологией разработки программных систем. В обучении этой технологии отводится существенное место. Остаются споры лишь о том, сразу или не сразу начинать обучение с введения классов и объектов. Важную роль в обучении играет язык программирования и среда разработки. К счастью, здесь есть конкуренция и на роль первого языка претендуют несколько языков - все еще сохраняет свои позиции язык С++, ему на пятки наступают более молодые конкуренты - Java и C#, сильна еще среда Delphi, есть и другие претенденты.
В докладе рассматриваются вопросы преподавания технологии ООП на языке C# в среде Visual Studio .NET. Основное внимание уделяется обсуждению ряда проблем ООП, возникающих при работе на C#.

Язык C# является одним из перспективных языков программирования, используемых при построении программных систем. У него масса достоинств. Но в этом докладе основное внимание уделяется некоторым проблемам, возникающим как при обучении объектно-ориентированное программирование, так и в реальной разработке программных систем. Рассматриваются важные ситуации из "жизни ООП", которые недостаточно хорошо описаны или реализованы в языке. В ряде случаев они могут приводить к ошибочным результатам.

Классы и модули

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

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

Рассмотрим, как этот вопрос решается в языке C#. Формально язык построен только на классах и понятия "модуль" нет на синтаксическом уровне. Тем не менее, эта конструкция присутствует в языке неявно. В языке есть описатель static, который может задаваться как для класса, так и для отдельных полей и методов класса. Класс с описателем static называется статическим классом, но фактически является модулем, существующим в единственном экземпляре. Чаще всего класс C# не является статическим, но таковыми являются некоторые из его полей и методов. Реально это означает, что такой класс имеет сопровождающий его модуль. Этот модуль может использоваться только для внутренних целей, позволяя объектам класса обмениваться между собой информацией и выполнять специальные операции. В этом случае статические поля и методы класса объявляются с модификатором доступа private или protected. Но модуль, сопровождающий класс, может быть полностью или частично открыт и для клиентов класса. Типичными примерами классов, представляющих собой модули, являются такие классы из библиотеки FCL как Math, Convert, Console. Многие классы из библиотеки FCL являются настоящими классами, но параллельно имеют и сопровождающие их модули. Типичным примером является класс String, явно задающий тип данных. Но и у него есть связанный с ним модуль. Из двух взаимно обратных методов класса - split и join, выполняющих расщепление строки и обратное объединение, split является методом класса и доступен объектам, а join - является static методом , включенным в модуль, связанный с классом.

Тема правильного проектирования класса и выделения его модульной компоненты является важной при обучении основам ООП.

Как корректно обрабатывать события классов

При проектировании класса важную роль играют события, которые могут происходить с объектами класса. В C# используется развитая и интересная схема работы с событиями. При проектировании класса определяются события, которые могут происходить с объектами классов. Динамически создаваемые объекты в процессе работы в конкретной ситуации могут "зажигать" события, посылая тем самым сообщение о возникновении события. Это сообщение доставляется объектам тех классов, которые подписались на получение сообщений о событии. Так событие "пожар", возникшее у объекта "город", может быть получено и обработано различными службами - скорой помощью, пожарными, милицией. Эта схема, введенная в C#, всем хороша, за исключением того, что она оставляет возможность возникновения конфликта между обработчиками событий. Вновь присоединенный обработчик события может нарушить корректность работающей системы.

В докладе подробно рассматриваются причины возникновения конфликтов и способы их устранения.

Как корректно обрабатывать исключительные ситуации

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

Уже говорилось, что в ООП нет единого взгляда на соотношение между классами и модулями программной системы, на то, как строить схему обработки событий. Такая же ситуация имеет место и для обработки исключительных ситуаций, - в разных языках эта обработка ведется по-разному. Рассмотрим, как это делается в C#, и насколько хороша предлагаемая схема.

Обработка исключительных ситуаций в C# предполагает схему try - catch блоков. Есть охраняемый try блок. Если в ходе выполнения этого блока возникает исключительная ситуация, то создается специальный объект - потомок класса Exception, свойства которого говорят о причине исключительной ситуации. Действия охраняемого блока в момент возникновения ситуации прерываются, и управление может перехватить один из catch блоков - блоков обработчиков исключительной ситуации, которому и передается объект Exception.

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

Схема обработки исключительных ситуаций, предложенная в языке C#, обладает существенным изъяном - ее можно применить некорректно. Она позволяет, в случае возникновения исключительной ситуации, уведомить о ее возникновении и спокойно продолжить работу, что, в конечном счете, может привести к неверным результатам. Из двух зол - прервать вычисление с уведомлением о невозможности продолжения работы или закончить вычисления с ошибочным результатом - следует выбрать первое зло.

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

DLL и пространства имен

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

Литература

  1. С. З. Свердлов "Языки программирования и методы трансляции". Изд. "Питер", 2007 г.
  2. В. А. Биллиг "Основы программирования на C#". Изд. "Бином", "Интернет-Университет ИТ", 2006 г.
  3. Б. Мейер "Объектно-ориентированное конструирование программных систем". Изд. "Русская Редакция", "Интернет-Университет ИТ", 2005 г.
 

В начало :: О конференции :: Программа :: Доклады :: Контакты

Техническая поддержка сайта:
Copyright © АП КИТ, 2005
hosted by TERCOM
webmasters: perez&helga