Я очень часто слышу и читаю в статьях про преимущества объектного подхода в программировании и недостатках функционального. Для меня это очень актуальный вопрос и я стараюсь изучить его во всех деталях. В первую очередь встает вопрос о том что же такое действительно Объект и по каким принципам он должен работать. Такие вещи как время жизни и обработка ошибок на прямую влияют на определение объекта как такового. Работая с различными языками программирования я постоянно сталкивался на не четкую модель объектного подхода и везде натыкался на подводные камни, которые убивали идеальную объектную модель.
Я долгое время работал с С++ и считал его лучшим языком, и как все начинающие отрицал существования чего-то более лучшего и надежного чем С++. Однако первый камень, который в меня попал был неудачный объект С++, после чего этот язык стал сдавать для меня позиции. Следующим языком была Java, в которой несмотря на все старания разработчиков создать объектный язык с простым синтаксисом и автоматическим сбором неиспользуемой памяти показал себя так же недостаточно продумано. Следующим шагом для меня стало изучение С# и тут же я сталкнулся с проблемами освобождения не managed ресурсов, что тем самым опять дополнило коллекцию языков не сопосбных создавать прозрачную объектную модель. На данный момент я вижу свет в конце тонеля, но это будет уже не обектный язык, как его называют, а функциональный и его имя Erlang. Мои текущие представления о его механизмах создания и уничтожения сущностей он соотвествует понятиям идеального объекта. Но это пока, что будет потом...
Что же я понимаю под определением объекта? В первую очередь это должна быть завершенная сущноть, она должна быть логически завершенной конструкцией и иметь в себе все варианты обработки исключительных ситуаций. Идея заключается в том, что бы записывать все действия относящиеся к какой-либо операции в одном месте. Будь-то создание объекта, его удаление, обновление или откат операции которую он не смог выполнить из за ошибки. Это определение становиться очень близко к определению транзакции, которая работатет с одной таблицей и уничтожает все изменения в случае ошибки или не возможности завершения транзации корректно. При этом транзация делает эту работу автоматически и нам нет необходимости откатывать изменения в ручную, создавая для этого дополнительные строчки когда по всему проекту. Кроме того, задача объекта быть созданным в момент иницаилазиции операции. И быть уничтоженным в случае ее завершения, успешного или нет. Получается что объект как сущность не должен существовать если в нем не содержится никаких действий при его иницализизации. Если это происходит следовательно объекту не требудется никаких завершающих операций, это озаначет что объект создан как хранилище набора функций и мы приходим к фукнциональному(модульному) программированию, а не к объектному . Другими словами объект, который создан но не иницализирован, не имеет смысла.
Теперь посмотрим на список языков привиденный выше и посмотрим какими проблеммами обладает каждый из них.
С++
- Объект не может быть быть создан и инициализирован одновременно, это приводит к ряду проблемм.
- Исключения в констукторе приводят к проблемам освобождения ресурсов уже иницализированных.
- Обект МОЖЕТ быть создан и не иницализирован, особенно простые типы.
- Проблемы вызваны наличием примитивов и отсутсвием их связи с объектами. В результате чего нет возможности однозначной идентификация обекта. Операция Switch(Object)/case Object не работает. Чтобы это исправить необходимо в ручную создавать связи между обектами и константами, так же как #define SOME 123;
- Освобождение внешних ресурсов требует дополнительных действий.
- Особождения не managed обектов в C# тербует создание дополнительных конструкций по всему коду. Особенно когда мы хотим иницализировать обект сразу после создания, приходится приминять исключения в конструкторах, когда ссылка на объект не присываивается переменной необхдимо писать обертки, как в самом конструкторе так и выше по стеку, что приводит к дублированию кода обработки ошибок.


1 коммент.: