Объектно-ориентированное программирование (c#)object-oriented programming (c#)
Содержание:
- Философия ООП ¶
- Фабричный метод без размещения в динамической памяти
- Variadic Templates, Low Coupling и немного размышлений
- Аналогия
- Обновление контролеров IDE ATA/ATAPI
- Определение классов в C++
- Проблемы структурного программирования
- Строительный блок программного проекта
- Хук ООП не друг или Динамическое автонаследование классов
- туроператоров: 12 самых надежных на сегодняшний день
- Как взять ипотеку пенсионеру?
- Абстракция
- Роль инкапсуляции
- Абстракция
- Удаленный рабочий стол Chrome: функции и утилиты
- Почему здравый смысл важнее паттернов, а Active Record не так уж и плох
- История развития
- ООБД без ООП
- Что такое ООП
Философия ООП ¶
Первое, что нужно понять, ООП это лишь один из способов организации кода. С помощью объектов мы разделяем большую логику на на много маленьких, чтобы нам легче было управлять своим же кодом. Это значит, что не нужно во все места совать классы и интерфейсы. Если ООП не упрощает код, а только запутывает, то это неправильное ООП! Каждый раз спрашивайте себя: «А что я упрощу, если сделаю объект?»
Но давайте вернёмся к примеру выше и посмотрим, как можно упростить себе жизнь.
Первое, на что нужно обратить внимание, это то, что мы работаем с пользователем как с массивом:
А что будет, если свойств у пользователя будет много или ключи массива будут меняться? Тогда придётся где-то вести документацию, какие ключи можно использовать, а какие нет. И кто-то должен будет контролировать, чтобы программисты использовали только правильные ключи. Оказывается, эту задачу можно переложить на среду исполнения, если использовать ООП.
Давайте создадим класс пользователя, который на вход принимает данные пользователя и имеет функцию для возврата имени:
Исправим объявление списка:
Теперь для доступа к имени пользователя можно использовать функцию . Мы «спрятали» (инкапсулировали) структуру исходного массива с данными пользователя за функциями класса . Если исходный массив поменяется, то изменения нужно будет внести только в функции класса.
Дальше решим проблему с постраничной навигацией. Поскольку базовый массив не поддерживает такую навигацию, «спрячем» его в объект, а уже объект «научим» выдавать страницы. Для начала опишем класс коллекции:
Изменим объявление исходных данных:
Теперь можно обращаться к нашим данным так:
Осталось решить проблему с форматом вывода пользователей. Дело в том, что в этом цикле является низкоуровневой логикой, которую надо «прятать». Собственно, также является лишним звеном в этой цепочке. В идеале логику отображения нужно вынести в шаблон и передавать ему список пользователей:
Шаблон представляет из себя псевдо язык разметки, в котором в теории удобно делать вёрстку:
Основная цель таких шаблонов — разделить логику отображения от логики данных. Преимущество, которое нам дают шаблоны заметны сразу: основной код стал «чище» и проще. Ходят легенды, что подобные шаблоны могут делать дизайнеры, верстальщики, папы, мамы, кошки без участия программистов. То есть налицо разделение труда (а если вспомнить историю за 5-й класс, то это уже прогресс в развитии).
Фабричный метод без размещения в динамической памяти
У классической реализации фабричного метода на C++ есть один существенный недостаток — используемый при реализации этого шаблона динамический полиморфизм предполагает размещение объектов в динамической памяти. Если при этом размеры создаваемых фабричным методом объектов не велики, а создаются они часто, то это может негативно сказаться на производительности. Это связанно с тем, что во первых оператор не очень эффективен при выделении памяти малого размера, а во вторых с тем что частая деаллокация небольших блоков памяти сама по себе требует много ресурсов.
Для решения этой проблемы было бы хорошо сохранить динамический полиморфизм (без него реализовать шаблон не получится) и при этом выделять память на стеке.
Если вам интересно, как это у меня получилось, добро пожаловать под кат.
Variadic Templates, Low Coupling и немного размышлений
Из песочницы
Каждый программист, наверняка, сталкивался с ситуацией, когда в приложении имеется набор классов (возможно, сервисных), которые используются во многих участках программы. И вроде бы всё ничего, но как только появлялась необходимость менять эти классы, это могло негативно влиять и на вызывающий код. Да, как и указано в заголовке, речь в статье пойдет о том самом паттерне «Low Coupling».
Проблема не нова и давно известна. Путей ее решения может быть несколько, все зависит от предметной области. Я предлагаю читателю возможное решение, которое я нашел, занимаясь прикладной задачей. Как идеалиста, найденное решение меня устроило не полностью. Так же, оно было спроектировано в бОльшей степени от желания воспользоваться новыми возможностями стандарта C++11. Естественно, все написанное подлежит обсуждению, а возможно, кто-то предложит более стройный вариант.
Аналогия
Можно представить объекты отделами компании. В большинстве организаций сотрудники не работают один день с кадрами, на следующий начисляя зарплату, а затем неделю занимаясь розничной торговлей. У каждого отдела есть свой персонал с четко возложенными на него обязанностями. Есть и собственные данные: показатели заработной платы, продаж, учет сотрудников и т. д. Люди в отделах работают со своей информацией. Разделение компании, таким образом, облегчает контроль за ее деятельностью и поддерживает целостность данных. Бухгалтерия отвечает за платежные ведомости. Если необходимо знать общую сумму заработной платы, выплачиваемой в южном филиале в июле, не нужно рыться в архиве. Достаточно направить записку ответственному лицу, подождать, пока этот человек получит доступ к данным и отправит ответ с требуемой информацией. Это гарантирует соответствие регламенту и отсутствие постороннего вмешательства. Таким же образом объект в ООП обеспечивает организацию приложения.
Следует помнить, что ориентация на объекты не касается подробностей работы программы. Большинство инструкций C++ соответствует операторам процедурных языков, таких как С. Действительно, функции-члены в C++ очень похожи на функции в С. Только более широкий контекст позволит установить, является ли инструкция процедурной или объектно-ориентированной.
Обновление контролеров IDE ATA/ATAPI
Ошибка DPC Watchdog Violation на синем экране может возникнуть после перехода с Windows 7 на 10, а также установки расширенного обновления. В некоторых случаях драйвера интерфейса подключения накопителей остаются незатронутыми при переходе/обновлении, в итоге система не может правильно распознать устройство из-за их несоответствия и выбрасывает синий экран.
В окне «Выполнить», которое открывается клавишами Win + R, впишите команду devmgmt.msc и нажмите на Enter для входа в «Диспетчер устройств».
Раскройте раздел «IDE ATA/ATAPI контроллеры» и выберите тот, который называется SATA AHCI. Кликните на нем правой кнопкой мыши и выберите «Обновить драйверы».
Перейдите ко второму варианту поиска драйверов на этом компьютере вручную. Затем выберите поиск из доступных драйверов на этом ПК.
Выберите стандартный контроллер AHCI Serial ATA и нажмите «Далее».
После перезагрузите компьютер. Посмотрите, препятствует ли работе за ПК синий экран с ошибкой DPC Watchdog Violation.
Определение классов в C++
Класс — это пользовательский тип данных (также как и структуры). Т.е. тип данных, который вы создаёте сами. Для этого вы пишете определение класса. Определение класса состоит из заголовка и тела. В заголовке ставится ключевое слов class, затем имя класса (стандартный идентификатор C++). Тело помещается в фигурные скобки. В C++ классы и структуры почти идентичны. В языке C в структурах можно хранить только данные, но в C++ в них можно добавить действия.
class Tank {
private:
int ammo;
public:
void Attack() {
ammo -= 1;
}
};
В C++ ключевые слова struct и class очень близки и могут использоваться взаимозаменяемо. У них есть только одно отличие (об этом ниже). Вот как можно определить такой же класс с помощью struct:
struct Tank {
private:
int ammo;
public:
void Attack() {
ammo -= 1;
}
};
Отличие только первом ключевом слове. В одном из прошлых уроков мы уже обсуждали структуры. что мы видим новое? Ключевые слова private и public — это спецификаторы доступа. Также мы видим, что внутри класса мы можем вставлять определения функций.
Определение класса это чертёж. Оно говорит нам из каких данных состоит класс и какие действия он может совершать. т.е. происходит объединение данных и действий в одной сущности.
Переменные и методы класса
Класс состоит из членов класса (class members). Члены класса могут быть переменными (data members) или методами (function members или methods). Переменные класса могут иметь любой тип данных (включая другие структуры и классы). Методы — это действия, которые может выполнять класс. По сути, это обычные функции.
Все методы класса имеют доступ к переменным класса
Обратите внимание, как мы обращаемся к ammo в методе Attack
Проблемы структурного программирования
Поскольку приложения становились все более крупными, структурное программирование начало испытывать трудности. Проекты становились слишком сложными. Графики сдвигались. Задействовалось большее число программистов. Сложность росла. Затраты взлетали, график сдвигался дальше, и наступал крах.
Анализ причин этих неудач показал недостатки процедурной парадигмы. Независимо от того, насколько хорошо реализован структурированный подход к программированию, крупные приложения становятся чрезмерно сложными.
Каковы причины этих проблем, связанных с процедурными языками? Во-первых, функции имеют неограниченный доступ к глобальным данным. Во-вторых, не связанные между собой процедуры и значения плохо моделируют реальный мир.
Если рассматривать эти проблемы в контексте программы учета запасов, то одним из важнейших глобальных элементов данных является совокупность учетных единиц. Разные функции могут обращаться к ним для ввода нового значения, его отображения, изменения и т. д.
Строительный блок программного проекта
Используя разные приемы абстракции, программист выполняет реализацию алгоритма в виде участка кода, который представляет собой обособленный и законченный элемент его труда. Этот элемент в зависимости от используемого языка программирования может представлять собой и функцию, и объект, и последовательность инструкций. Назовем для удобства дальнейшего изложения этот фрагмент кода словом «компонент».
Компонент — участок кода (процедура, класс, deployment component и т.д.):
- который реализует некоторый законченный алгоритм, работающий в определенных начальных ситуациях и с определенными входными данными,
- который возможно использовать несколько раз в одном проекте (еще лучше много раз в разных проектах),
- все инструкции которого расположены близко и просматриваются без необходимости дополнительных поисковых операций в среде разработки,
- изменения в котором программист выполняет относительно независимо по отношению к остальным участкам кода.
Хук ООП не друг или Динамическое автонаследование классов
Нет предела совершенству. Поэтому, какая бы хорошая и многофункциональная CMS не была, но у сторонних разработчиков всегда будет возникать необходимость ее надстроить, допилить, расширить каким-то своим функционалом. И, конечно, любой современный движок должен позволять это делать.
Причем, механизм расширения функционала движка должен позволять «вешать» на него любое число расширений, написанных разными разработчики, которые не знают ни друг о друге, ни о расширениях, которые пишут другие разработчики.
В различных движках это может делаться разными способами. Наиболее распространенный, наверное, это хуки – сторонний разработчик, создающий расширение для движка, регистрирует обработчики хуков, а потом эти обработчики вызываются системой в нужных местах, выполняя код расширения.
Но когда движок написан с использованием ООП и все разложено на классы, то использование хуков – как это чужеродно и «костыльно», и хочется более чистого и более простого ООП-подхода, когда в создаваемом расширении просто расширяется «коробочный» класс с перекрытием родительских методов.
Вот для решения таких задач и был придуман способ, который я назвал «Динамическое автонаследование».
туроператоров: 12 самых надежных на сегодняшний день
Как взять ипотеку пенсионеру?
Продолжаем разбираться с тем, можно ли пенсионерам взять ипотеку на дом и на сколько лет её дают?
Чтобы получить кредитование по спецпрограмме сперва нужно обратиться в банк и узнать, предусмотрена ли там такая программа, можно ли получить ипотеку пенсионеру по ней?.
Если да, то чтобы оформить ипотеку нужно собирать документы.
А их потребуется немало:
- заявление;
- справка из Пенсионного фонда;
- общегражданское удостоверение личности;
- техпаспорт;
- кадастровый паспорт;
- документы о праве собственности на жилище;
- выписка из ЕГРП;
- документ из Управляющей компании об отсутствии задолженности;
- справка с работы;
- копия трудовой книжки;
- правоустанавливающие бумаги на имеющуюся недвижимость или машину;
- иные справки о доходах.
Как уже говорилось, обязательно потребуют оформить страхование жизни. Так что нужна будет еще и справка о здоровье.
Обычно банк рассматривает заявку в течение одной рабочей недели. Но этот срок может быть и увеличен при сложной ситуации. Могут запросить и дополнительные документы, подтверждающие надежность клиента.
Абстракция
Абстракция означает предоставление только необходимого функционала конечному пользователю. Вам не нужно понимать, как работает двигатель для управления автомобилем. Все, что вам нужно знать, это как завести автомобиль, как добавить газу, притормозить и остановиться. Вам не нужно особо думать над тем, что под капотом автомобиля есть двигатель, топливный насос, фильтры, радиатор и т. д.
Кроме того, каждая из этих частей состоит из других частей, которые также входят в состав других частей. Двигатель имеет цилиндры, свечи зажигания и т. д. Вообщем, абстракция — это когда наш класс Car предоставляет только четыре метода (завести мотор, добавить газу, притормозить, остановиться) и скрывает другие сложные детали своего функционала.
Для использования класса Car вам не нужно понимать, как там все устроено изнутри. Точно так же и водителю автомобиля необязательно знать, как работает двигатель.
Роль инкапсуляции
Инкапсуляция — это механизм программирования, объединяющий вместе код
и данные, которыми он манипулирует, исключая как вмешательство извне, так и неправильное использование данных. В объектно-ориентированном языке данные и код
могут быть объединены в совершенно автономный черный ящик. Внутри такого ящика
находятся все необходимые данные и код. Когда код и данные связываются вместе подобным образом, создается объект. Иными словами, объект — это элемент, поддерживающий инкапсуляцию.
Т.е. инкапсуляция представляет собой способности языка скрывать излишние детали реализации от пользователя объекта.
Например, предположим, что используется класс по имени DatabaseReader, который
имеет два главных метода: Open() и Close().
Фиктивный класс DatabaseReader инкапсулирует внутренние детали нахождения,
загрузки, манипуляций и закрытия файла данных. Программистам нравится инкапсуляция, поскольку этот принцип ООП упрощает кодирование. Нет необходимости беспокоиться о многочисленных строках кода, которые работают «за кулисами», чтобы
реализовать функционирование класса DatabaseReader. Все, что потребуется — это
создать экземпляр и отправлять ему соответствующие сообщения (например, «открыть файл по имени AutoLot.mdf, расположенный на диске С:»).
С идеей инкапсуляции программной логики тесно связана идея защиты данных.
В идеале данные состояния объекта должны быть специфицированы с использованием ключевого слова private (или, возможно, protected). Таким образом, внешний мир
должен вежливо попросить, если захочет изменить или получить лежащее в основе значение. Это хороший принцип, поскольку общедоступные элементы данных можно легко повредить (даже нечаянно, а не преднамеренно).
Основной единицей инкапсуляции в C# является класс, который определяет форму
объекта. Он описывает данные, а также код, который будет ими оперировать. В C# описание класса служит для построения объектов, которые являются экземплярами
класса. Следовательно, класс, по существу, представляет собой ряд схематических описаний способа построения объекта.
Код и данные, составляющие вместе класс, называют членами. Данные, определяемые классом, называют полями, или переменными экземпляра. А код, оперирующий
данными, содержится в функциях-членах, самым типичным представителем которых
является метод. В C# метод служит в качестве аналога подпрограммы. (К числу других
функций-членов относятся свойства, события и конструкторы.) Таким образом, методы класса содержат код, воздействующий на поля, определяемые этим классом.
Абстракция
Тут всё предельно просто. При абстракции выделяются главные и наиболее значимые характеристики предмета, одновременно с этим отбрасываются второстепенные и незначительные.
Простой пример: представьте, что мы создаём картотеку сотрудников компании. Естественно, мы вносим их основные характеристики: дату рождения, ИНН, ФИО, номер социального страхования. Разумеется, нас не интересуют ни рост, ни цвет глаз, ни длина волос. То есть мы абстрагируемся от ненужной информации.
А что если нужно создать картотеку модельного агентства? Согласитесь, что здесь ситуация кардинально меняется и вряд ли нам понадобится индивидуальный номер налогоплательщика, а вот данные о внешности будут очень кстати.
Удаленный рабочий стол Chrome: функции и утилиты
Удаленный рабочий стол Chrome предоставляет несколько полезных функций, которые упрощают работу и позволяют использовать несколько устройств. В то время как использование рабочего стола из другого места может вызвать некоторые материально-технические проблемы, Chrome Remote Desktop позволяет легко избежать наиболее распространенных проблем.
Удаленная поддержка упрощает процесс устранения неполадок. (Изображение предоставлено Google)
Например, если вы используете мобильное устройство, вы можете переключиться в режим клавиатуры или трекпада с помощью кнопки меню в левом нижнем углу. Приложение также включает в себя выделенные пункты меню для Ctrl-Alt-Del и Print Screen.
Мы протестировали Chrome Remote Desktop, получив доступ к iMac 2015 через iPhone SE. К сожалению, в приложении отсутствовали такие важные клавиши, как Command, Control и Option, поэтому многие важные сочетания клавиш были просто недоступны.
С другой стороны, вы должны иметь возможность использовать компьютер удаленно без каких-либо проблем на другом компьютере или ноутбуке. Вы можете перенастроить сопоставления клавиш, если оба устройства имеют физическую клавиатуру. Тем не менее, Chrome Remote Desktop не позволяет передавать файлы между устройствами.
Существует также опция для удаленной поддержки, которая дает удаленным пользователям одноразовый код для доступа к рабочему столу для устранения любых проблем. Это позволяет ИТ-специалистам быстро решать проблемы без физического присутствия или получения постоянного доступа.
Почему здравый смысл важнее паттернов, а Active Record не так уж и плох
Так уж вышло, что разработчики, особенно молодые, любят паттерны, любят спорить о том, какой паттерн нужно применять здесь или там. Спорить до хрипоты: это фасад или прокси, а может даже синглтон. А если у вас не чистая, гексагональная архитектура, то некоторые разработчики готовы сжечь на костре Святой Инквизиции.
При этом они забывают, что паттерны — это лишь возможные решения
У паттернов, также как и у любых принципов, есть границы применимости, и важно их понимать. Дорога в ад вымощена слепым и религиозным следованием пусть даже и авторитетным словам
А наличие во фреймворке нужных паттернов никак не гарантирует их правильного и осознанного применения.
История развития
Основа ООП была заложена в начале 1960-х годов. Прорыв в использовании экземпляров и объектов был достигнут в MIT с PDP-1, и первым языком программирования для работы с объектами стал Simula 67. Он был разработан Кристен Найгаард и Оле-Джохан Даль в Норвегии с целью создания симуляторов. Они работали над симуляциями взрыва кораблей и поняли, что могут сгруппировать корабли в различные категории. Каждому типу судна было решено присвоить свой собственный класс, который должен содержать в себе набор уникальных характеристик и данных. Таким образом, Simula не только ввела понятие класса, но и представила рабочую модель.
Термин «объектно-ориентированное программирование» был впервые использован Xerox PARC в языке программирования Smalltalk. Понятие ООП использовалось для обозначения процесса использования объектов в качестве основы для расчетов. Команда разработчиков была вдохновлена проектом Simula 67, но они спроектировали свой язык так, чтобы он был динамичным. В Smalltalk объекты могут быть изменены, созданы или удалены, что отличает его от статических систем, которые обычно используются. Этот язык программирования также был первым, использовавшим концепцию наследования. Именно эта особенность позволила Smalltalk превзойти как Simula 67, так и аналоговые системы программирования.
Simula 67 стала новаторской системой, которая впоследствии стала основой для создания большого количества других языков программирования, в том числе Pascal и Lisp. В 1980-х годах объектно-ориентированное программирование приобрело огромную популярность, и основным фактором в этом стало появление языка С++
Концепция ООП также имела важное значение для разработки графических пользовательских интерфейсов. В качестве одного из самых ярких примеров можно привести структуру Cocoa, существующую в Mac OS X
Общие принципы модели стали применяться во многих современных языках программирования. Некоторые из них — Fortran, BASIC, Pascal. На тот момент многие программы не были разработаны с учетом ООП, что было причиной возникновения некоторых проблем совместимости. “Чистые” объектно-ориентированные языки программирования не обладали многими функциями, необходимыми программистам. Для решения этих проблем ряд исследователей предложили несколько новых языков программирования, созданных на основе принципов ООП с сохранением других, необходимых программистам, функций. Среди наиболее ярких примеров можно выделить Eiffel, Java, .NET. Даже в серьезных веб-разработках используются языки программирования, основанные на принципах ООП — PHP (у нас вы можете пройти курс ООП в PHP), Python, Ruby. По мнению экспертов, в ближайшие несколько десятилетий именно объектно-ориентированный подход будет оставаться основной парадигмой в развитии программирования.
ООБД без ООП
Из песочницы
Лично мне не надо объяснять, что такое ООП. Я сам в первую очередь мыслю существительными и только во вторую — глаголами.
Но речь не о том, кто как мыслит; я хочу обсудить ситуацию, когда отказ от привычных механизмов ООП упрощает работу с объектами.
Как, пример, можно вспомнить добрым словом Lotus Notes, где имя формы хранилось внутри документа. Создавая форму LN, мы тем самым описываем новый UI класс, в котором можно добавлять свойства и переопределять методы (Queryopen, Postsave и пр.). При этом новый объект, созданный с помощью этой формы, не связан с ней механизмом наследования. Форма – это свойство объекта, и в LN есть команда «SwitchForm», с помощью которой можно открыть объект с другой формой, естественно, с вызовом других методов. Неопределенные свойства при этом вернут пустую строку.
Что такое ООП
Возникло как результат развития процедурного программирования. Основой объектно-ориентированных языков являются такие принципы, как:
- инкапсуляция;
- наследование;
- полиморфизм.
Некоторые принципы, которые были изначально заложены в первые ООЯ, подверглись существенному изменению.
Примеры объектно-ориентированных языков:
- Pascal. С выходом Delphi 7 на официальном уровне стал называться Delphi. Основная область использования Object Pascal — написание прикладного ПО.
- C++ широко используется для разработки программного обеспечения, является одним из самых популярных языков. Применяется для создания ОС, прикладных программ, драйверов устройств, приложений, серверов, игр.
- Java — транслируется в байт-код, обрабатывается виртуальной машиной Java. Преимуществом такого способа выполнения является независимость от операционной системой и оборудования. Существующие семейства: Standard Edition, Enterprise Edition, Micro Edition, Card.
- JavaScript применяется в качестве языка сценариев для web-страниц. Синтаксис во многом напоминает Си и Java. Является реализацией Ecmascript. Сам Ecmascript используется в качестве основы для построения других скриптовых языков, таких как JScript, ActionScript.
- Objective-C построен на основе языка Си, а сам код Си понятен компилятору Objective-C.
- Perl — высокоуровневый интерпретируемый динамический язык общего назначения. Имеет богатые возможности для работы с текстом, изначально разработан именно для манипуляций с текстом. Сейчас используется в системном администрировании, разработке, сетевом программировании, биоинформатике и т. д.
- PHP. Аббревиатура переводится как препроцессор гипертекста. Применяется для разработки веб-приложений, в частности серверной части. С его помощью можно создавать gui-приложения с помощью пакетов PHP-GTK, PHP-Qt, WinBinder.
- Python — язык общего назначения, ориентирован на повышение производительности разработчика и читаемость кода. Был разработан проект Cython, с помощью которого осуществляется трансляция программ, написанных на Python в код на языке Си.