Я не знаю ООП / Хабр

Я не умею программировать на объектно-ориентированных языках. Не научился. После 5 лет промышленного программирования на Java я всё ещё не знаю, как создать хорошую систему в объектно-ориентированном стиле. Просто не понимаю.

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

И вот несколько вещей, которые вызывают у меня непонимание.

Я не знаю, что такое ООП

Серьёзно. Мне сложно сформулировать основные идеи ООП. В функциональном программировании одной из основных идей является отсутствие состояния. В структурном — декомпозиция. В модульном — разделение функционала в законченные блоки. В любой из этих парадигм доминирующие принципы распространяются на 95% кода, а язык спроектирован так, чтобы поощрять их использование. Для ООП я таких правил не знаю.

Принято считать, что объектно-ориентированное программирование строится на 4 основных принципах (когда я был мал, их было всего 3, но ведь тогда и деревья были большими). Эти принципы:

  • Абстракция
  • Инкапсуляция
  • Наследование
  • Полиморфизм

Смахивает на свод правил, не так ли? Значит вот оно, те самые правила, которым нужно следовать в 95% случаев? Хмм, давайте посмотрим поближе.

Абстракция

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

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

Во-вторых, абстракции в программировании были всегда, начиная с записей Ады Лавлейс, которую принято считать первым в истории программистом. С тех пор люди бесперерывно создавали в своих программах абстракции, зачастую имея для этого лишь простейшие средства. Так, Абельсон и Сассман в своей небезызвестной книге описывают, как создать систему решения уравнений с поддержкой комплексных чисел и даже полиномов, имея на вооружении только процедуры и связные списки. Так какие же дополнительные средства абстрагирования несёт в себе ООП? Понятия не имею. Выделение кода в подпрограммы? Это умеет любой высокоуровневый язык. Объединение подпрограмм в одном месте? Для этого достаточно модулей. Типизация? Она была задолго до ООП. Пример с системой решения уравнений хорошо показывает, что построение уровней абстракции не столько зависит от средств языка, сколько от способностей программиста.

Инкапсуляция

Главный козырь инкапсуляции в сокрытии реализации. Клиентский код видит только интерфейс, и только на него может рассчитывать. Это развязывает руки разработчикам, которые могут решить изменить реализацию. И это действительно круто. Но вопрос опять же в том, причём тут ООП? Все вышеперечисленные парадигмы подразумевают сокрытие реализации. Программируя на C вы выделяете интерфейс в header-файлы, Oberon позволяет делать поля и методы локальными для модуля, наконец, абстракция во многих языках строится просто посредствам подпрограмм, которые также инкапсулируют реализацию. Более того, объектно-ориентированные языки сами зачастую

нарушают правило инкапсуляции, предоставляя доступ к данным через специальные методы — getters и setters в Java, properties в C# и т.д. (В комментариях выяснили, что некоторые объекты в языках программирования не являются объектами с точки зрения ООП: data transfer objects отвечают исключительно за перенос данных, и поэтому не являются полноценными сущностями ООП, и, следовательно, для них нет необходимости сохранять инкапсуляцию. С другой стороны, методы доступа лучше сохранять для поддержания гибкости архитектуры. Вот так всё непросто.) Более того, некоторые объектно-ориентированные языки, такие как Python, вообще не пытаются что-то скрыть, а расчитывают исключительно на разумность разработчиков, использующих этот код.

Наследование

Наследование — это одна из немногих новых вещей, которые действительно вышли на сцену благодаря ООП. Нет, объектно-ориентированные языки не создали новую идею — наследование вполне можно реализовать и в любой другой парадигме — однако ООП впервые вывело эту концепцию на уровень самого языка. Очевидны и плюсы наследования: когда вас почти устраивает какой-то класс, вы можете создать потомка и переопределить какую-то часть его функциональности. В языках, поддерживающих множественное наследование, таких как C++ или Scala (в последней — за счёт traits), появляется ещё один вариант использования — mixins, небольшие классы, позволяющие «примешивать» функциональность к новому классу, не копируя код.

Значит, вот оно — то, что выделяет ООП как парадигму среди других? Хмм… если так, то почему мы так редко используем его в реальном коде? Помните, я говорил про 95% кода, подчиняющихся правилам доминирующей парадигмы? Я ведь не шутил. В функцинальном программировании не меньше 95% кода использует неизменяемые данные и функции без side-эффектов. В модульном практически весь код логично расфасован по модулям. Преверженцы структурного программирования, следуя заветам Дейкстры, стараются разбивать все части программы на небольшие части. Наследование используется гораздо реже. Может быть в 10% кода, может быть в 50%, в отдельных случаях (например, при наследовании от классов фреймворка) — в 70%, но не больше. Потому что в большинстве ситуаций это просто

не нужно.

Более того, наследование опасно для хорошего дизайна. Настолько опасно, что Банда Четырех (казалось бы, проповедники ООП) в своей книге рекомендуют при возможности заменять его на делегирование. Наследование в том виде, в котором оно существует в популярных ныне языках ведёт к хрупкому дизайну. Унаследовавшись от одного предка, класс уже не может наследоваться от других. Изменение предка так же становится опасным. Существуют, конечно, модификаторы private/protected, но и они требуют неслабых экстрасенсорных способностей для угадывания, как класс может измениться и как его может использовать клиентский код. Наследование настолько опасно и неудобно, что крупные фреймворки (такие как Spring и EJB в Java) отказываются от них, переходя на другие, не объектно-ориентированные средства (например, метапрограммирование). Последствия настолько непредсказуемы, что некоторые библиотеки (такие как Guava) прописывает своим классам модификаторы, запрещающие наследование, а в новом языке Go было решено вообще отказаться от иерархии наследования.

Полиморфизм

Пожалуй, полиморфизм — это лучшее, что есть в объектно-ориентированном программировании. Благодаря полиморфизму объект типа Person при выводе выглядит как «Шандоркин Адам Имполитович», а объект типа Point — как «[84.23 12.61]». Именно он позволяет написать «Mat1 * Mat2» и получить произведение матриц, аналогично произведению обычных чисел. Без него не получилось бы и считывать данные из входного потока, не заботясь о том, приходят они из сети, файла или строки в памяти. Везде, где есть интерфейсы, подразумевается и полиморфизм.

Мне правда нравится полиморфизм. Поэтому я даже не стану говорить о его проблемах в мейнстримовых языках. Я также промолчу про узость подхода диспетчеризации только по типу, и про то, как это могло бы быть сделано. В большинстве случаев он работает как надо, а это уже неплохо. Вопрос в другом: является ли полиморфизм тем самым принципом, отличающим ООП от других парадигм? Если бы вы спросили меня (а раз уж вы читаете этот текст, значит, можно считать, что спросили), я бы ответил «нет». И причина всё в тех же процентах использования в коде. Возможно, интерфейсы и полиморфные методы встречаются немного чаще наследования. Но сравните количество строк кода, занимаемое ими, с количеством строк, написанных в обычном процедурном стиле — последних всегда больше. Глядя на языки, поощряющие такой стиль программирования, я не могу назвать их полиморфными. Языки с поддержкой полиморфизма — да, так нормально. Но не полиморфные языки.

(Впрочем, это моё мнение. Вы всегда можете не согласиться.)

Итак, абстракция, инкапсуляция, наследование и полиморфизм — всё это есть в ООП, но ничто из этого не является его неотъемлемым атрибутом. Тогда что такое ООП? Есть мнение, что суть объектно-ориентированного программирования лежит в, собственно, объектах (звучит вполне логично) и классах. Именно идея объединения кода и данных, а также мысль о том, что объекты в программе отражают сущности реального мира. К этому мнению мы ещё вернёмся, но для начала расставим некоторые точки над i.

Чьё ООП круче?

Из предыдущей части видно, что языки программирования могут сильно отличаться по способу реализации объектно-ориентированного программирования. Если взять совокупность всех реализаций ООП во всех языках, то вероятнее всего вы не найдёте вообще ни одной общей для всех черты. Чтобы как-то ограничить этот зоопарк и внести ясность в рассуждения, я остановлюсь только одной группе — чисто объекто-ориентированные языки, а именно Java и C#. Термин «чисто объектно-ориентированный» в данном случае означает, что язык не поддерживает другие парадигмы или реализует их через всё то же ООП. Python или Ruby, например, не буду являться чистыми, т.к. вы вполне можете написать полноценную программу на них без единого объявления класса.

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

Smalltalk. В отличие от своих современных коллег, этот язык имел динамическую типизацию и использовал message-passing style для реализации ООП. Вместо вызовов методов объекты посылали друг другу сообщения, а если получатель не мог обработать то, что пришло, он просто пересылал сообщение кому-то ещё.

Common Lisp. Изначально CL придерживался такой же парадигмы. Затем разработчики решили, что писать `(send obj ‘some-message)` — это слишком долго, и преобразовали нотацию в вызов метода — `(some-method obj)`. На сегодняшний день Common Lisp имеет развитую систему объектно-ориентированного программирования (CLOS) с поддержкой множественного наследования, мультиметодов и метаклассов. Отличительной чертой является то, что ООП в CL крутится не вокруг объектов, а вокруг обобщённых функций.

Clojure. Clojure имеет целых 2 системы объектно-ориентированного программирования — одну, унаследованную от Java, и вторую, основанную на мультиметодах и более похожую на CLOS.

R. Этот язык для статистического анализа данных также имеет 2 системы объектно-ориентированного программирования — S3 и S4. Обе унаследованы от языка S (что не удивительно, учитывая, что R — это open source реализация коммерческого S). S4 по большей части соотвествует реализациям ООП в современных мейнстримовых языках. S3 является более легковесным вариантом, элементарно реализуемым средствами самого языка: создаётся одна общая функция, диспетчеризирующая запросы по атрибуту «class» полученного объекта.

JavaScript. По идеологии похож на Smalltalk, хотя и использует другой синтаксис. Вместо наследования использует прототипирование: если искомого свойства или вызванного метода в самом объекте нет, то запрос передаётся объекту-прототипу (свойство prototype всех объектов JavaScript). Интересным является факт, что поведение всех объектов класса можно поменять, заменив один из методов прототипа (очень красиво, например, выглядит добавление метода `.toBASE64` для класса строки).

Python. В целом придерживается той же концепции, что и мейнcтримовые языки, но кроме этого поддерживает передачу поиска атрибута другому объекту, как в JavaScript или Smalltalk.

Haskell. В Haskell вообще нет состояния, а значит и объектов в обычном понимании. Тем не менее, своеобразное ООП там всё-таки есть: типы данных (types) могут принадлежать одному или более классам типов (type classes). Например, практически все типы в Haskell состоят в классе Eq (отвечает за операции сравнения 2-х объектов), а все числа дополнительно в классах Num (операции над числами) и Ord (операции <, <=, >=, >). В менстримовых языках типам соответствуют классы (данных), а классам типов — интерфейсы.

Stateful или Stateless?

Но вернёмся к более распространённым системам объектно-ориентированного программирования. Чего я никогда не мог понять, так это отношения объектов с внутренним состоянием. До изучения ООП всё было просто и прозрачно: есть структуры, хранящие несколько связанных данных, есть процедуры (функции), их обрабатывающие. выгулять(собаку), снятьс(аккаунт, сумма). Потом пришли объекты, и это было тоже ничего (хотя читать программы стало гораздо сложней — моя собака выгуливала [кого?], а аккаунт снимал деньги [откуда?]). Затем я узнал про сокрытие данных. Я всё ещё мог выгулять собаку, но вот посмотреть состав её пищи уже не мог. Пища не выполняла никаких действий (наверное, можно было написать, что пища.съесть(собака), но я всё-таки предпочитаю, чтобы моя собака ела пищу, а не наоборот). Пища — это просто данные, а мне (и моей собаке) нужно было просто получить к ним доступ. Всё просто. Но в рамки парадигмы влезть было уже невозможно, как в старые джинсы конца 90-х.

Ну ладно, у нас есть методы доступа к данным. Пойдём на этот маленький самообман и притворимся, что данные у нас действительно скрыты. Зато я теперь знаю, что объекты — это в первую очередь данные, а потом уже, возможно, методы их обрабатывающие. Я понял, как писать программы, к чему нужно стремиться при проектировании.

Не успел я насладиться просветлением, как увидил в интернетах слово stateless (готов поклясться, оно было окружено сиянием, а над буквами t и l висел нимб). Короткое изучение литературы открыло чудесный мир прозрачного потока управления и простой многопоточности без необходимости отслеживать согласованность объекта. Конечно, мне сразу захотелось прикоснуться к этому чудесному миру. Однако это означало полный отказ от любых правил — теперь было непонятно, следует ли собаке самой себя выгуливать, или для этого нужен специальный ВыгулМенеджер; нужен ли аккаунт, или со всей работой справится Банк, а если так, то должен он списывать деньги статически или динамически и т.д. Количество вариантов использования возрасло экспоненциально, и все варианты в будущем могли привести к необходимости серьёзного рефакторинга.

Я до сих пор не знаю, когда объект следует сделать stateless, когда stateful, а когда просто контейнером данных. Иногда это очевидно, но чаще всего нет.

Типизация: статическая или динамическая?

Еща одна вещь, с которой я не могу определиться относительно таких языков, как C# и Java, это являются они статически или динамически типизированными. Наверное большинство людей воскликнет «Что за глупость! Конечно статически типизированными! Типы проверяются во время компиляции!». Но действительно ли всё так просто? Правда ли, что программист, прописывая в параметрах метода тип X может быть уверен, что в него всегда будут передаваться объекты именно типа X? Верно — не может, т.к. в метод X можно будет передать параметр типа X или его наследника. Казалось бы, ну и что? Наследники класса X всё равно будут иметь те же методы, что и X. Методы методами, а вот логика работы может оказаться совершенно другой. Самый распространённый случай, это когда дочерний класс оказывается соптимизированным под другие нужды, чем X, а наш метод может рассчитывать именно на ту оптимизацию (если вам такой сценарий кажется нереалистичным, попробуйте написать плагин к какой-нибудь развитой open source библиотеке — либо вы потратите несколько недель на разбор архитектуры и алгоритмов библиотеки, либо будете просто наугад вызывать методы с подходящей сигнатурой). В итоге программа работает, однако скорость работы падает на порядок. Хотя с точки зрения компилятора всё корректно. Показательно, что Scala, которую называют наследницей Java, во многих местах по умолчанию разрешает передавать только аргументы именно указанного типа, хотя это поведение и можно изменить.

Другая проблема — это значение null, которое может быть передано практически вместо любого объекта в Java и вместо любого Nullable объекта в C#. null принадлежит сразу всем типам, и в то же время не принадлежит ни одному. null не имеет ни полей, ни методов, поэтому любое обращение к нему (кроме проверки на null) приводит к ошибке. Вроде бы все к этому привыкли, но для сравнения Haskell (да и та же Scala) заставлют использовать специальные типы (Maybe в Haskell, Option в Scala) для обёртки функций, которые в других языках могли бы вернуть null. В итоге про Haskell часто говорят «скомпилировать программу на нём сложно, но если всё-таки получилось, значит скорее всего она работает корректно».

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

Какая разница, как называется такая типизация, если все правила всё равно известны? Разница в том, с какой стороны подходить к проектированию архитектуры. Существует давний спор, как строить систему: делать много типов и мало функций, или мало типов и много функций? Первый подход активно используется в Haskell, второй в Lisp. В современных объектно-ориентированных языках используется что-то среднее. Я не хочу сказать, что это плохо — наверное у него есть свои плюсы (в конце концов не стоит забывать, что за Java и C# стоят мультиязыковые платформы), но каждый раз приступая к новому проекту я задумываюсь, с чего начать проектирования — с типов или с функционала.

И ещё…

Я не знаю, как моделировать задачу. Считается, что ООП позволяет отображать в программе объекты реального мира. Однако в реальности у меня есть собака (с двумя ушами, четырмя лапами и ошейником) и счёт в банке (с менеджером, клерками и обеденным перерывом), а в программе — ВыгулМенеджер, СчётФабрика… ну, вы поняли. И дело не в том, что в программе есть вспомогательные классы, не отражающие объекты реального мира. Дело в том, что поток управления изменяется. ВыгулМенеджер лишает меня удовольствия от прогулки с собакой, а деньги я получаю от бездушного БанкСчёта (эй, где та милая девушка, у которой я менял деньги на прошлой неделе?).

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

Я также не знаю, как правильно декомпозировать функционал. В Python или C++, если мне нужна была маленькая функция для преобразования строки в число, я просто писал её в конце файла. В Java или C# я вынужден выносить её в отдельный класс StringUtils. В недо-ОО-языках я мог объявить ad hoc обёртку для возврата двух значений из функции (снятую сумму и остаток на счету). В ООП языках мне придётся создать полноценный класс РезультатТранзакции. И для нового человека на проекте (или даже меня самого через неделю) этот класс будет выглядеть точно таким же важным и фундаментальным в архитектуре системы. 150 файлов, и все одинаково важные и фундаментальные — о да, прозрачная архитектура, прекрасные уровни абстракции.

Я не умею писать эффективные программы. Эффективные программы используют мало памяти — иначе сборщик мусора будет постоянно тормозить выполнение. Но чтобы совершить простейшую операцию в объектно-ориентированных языках приходится создавать дюжину объектов. Чтобы сделать один HTTP запрос мне нужно создать объект типа URL, затем объект типа HttpConnection, затем объект типа Request… ну, вы поняли. В процедурном программировании я бы просто вызвал несколько процедур, передав им созданную на стеке структуру. Скорее всего, в памяти был бы создан всего один объект — для хранения результата. В ООП мне приходится засорять память постоянно.

Возможно, ООП — это действительно красивая и элегантная парадигма. Возможно, я просто недостаточно умён, чтобы понять её. Наверное, есть кто-то, кто может создать действительно красивую программу на объектно-ориентированном языке. Ну что ж, мне остаётся только позавидовать им.

habr.com

Основные принципы ООП и их использование

Общая информация

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

Основные принципы ООП

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

Инкапсуляция

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

Наследование

Второй принцип ООП — наследование — это возможность одного класса использовать методы другого без повторения их фактической реализации. Наследование позволяет избавиться от избыточности исходного кода.

Полиморфизм

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

Языки ООП

Принципы ООП используются в таких наиболее популярных языках программирования, как C++ и Java, на которых разработана значительная часть программ и приложений. Есть и менее используемые языки ООП — это Delphi, Object Pascal, Ruby и многие другие.

Критика ООП

Несмотря на в основном позитивные высказывания в сторону данной методологии, нередко принципы ООП подвергаются и критике. Как и у процедурного программирования, у ООП есть свои недостатки.

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

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

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

fb.ru

Процедурное против объектно-ориентированного? | Около программирования

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

Стиль решения задачи зависит от того, на сколько сложен будет алгоритм её решения. Если вы, к примеру, можете её решить выполнив одно действие потом другое, затем, если не получится сделать третье, то вы выполните четвёртое — это процедурный стиль или по-другому — процедурное программирование (ПП). Инструкции для решения задачи выполняются одна за другой, сверху вниз, иногда возникают изменения в их последовательности. Среди команд нельзя выделить приоритетные, для решения задачи они просто должны быть выполнены.

Решение задачи в объектно-ориентированном стиле, применяя объектно-ориентированное программирование (ООП), оказывается ближе к реальности. Сложные задачи — это стихия ООП. В решении задачи участвуют программные объекты и ответственность за решение делится между ними. Часто, в процессе можно найти некоторые паттерны, поэтому при решении задачи некоторый участок кода используется многократно. Результат достигается путём распределения ответственности между объектами программы и повторным использования промежуточных решений.

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

Это должен носить у сердца каждый программист

Пока вы ещё не наворотили много трудно-читаемого и понимаемого кода, запишите себе на видном месте два принципа. Без них может получится “чёпопало” в ваших программах.
Запишите себе — DRY и KISS.

DRY (Don’t Repeat Yourself) — Не Повторяйся.
KISS (Keep It Simple, Stupid) — Не Усложняй, Тупица.

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

Второй принцип — не усложняй, тупица! Звучит грубо, но довольно самокритично, так как это произносится всё-таки внутренним голосом. Действительно, зачем всё усложнять? Код должен решать задачу и всё, он не должен показывать ваши амбиции. Усложнять глупо, вы вообще учитываете что вы сами потом к этому коду вернётесь, чтобы найти в нём закравшуюся ошибку? Для написанного вами класса это означает, что каждый метод решает элементарную задачу. Если это не так, код надо реорганизовать и превратить один метод в два или больше.

Следовать этим принципам вам поможет использование шаблонов проектирования или паттернов. Некоторые даже рекомендуют начинать изучение ООП с этого. Но паттернов очень много. И пока вы их изучаете можно вообще забыть про цель.

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

Не кидайтесь сразу в изучение паттернов, получите опыт ООП на простых задачах, чтобы хоть как-то представлять, что там к чему. И уже потом, тада када …, ныряйте в паттерны на здоровье.

Проведём мысленный эксперимент

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

  • Площадь
  • Количество комнат
  • Тип дома
  • Цена
  • Этаж
  • Наличие балкона

Для коттеджей практически тоже самое:

  • Площадь
  • Количество комнат
  • Тип дома
  • Цена
  • Количество этажей
  • Отопление
  • Приусадебный участок

В ПП вы сразу начинаете писать функции, для обработки форм ввода и вывода данных для квартиры и для коттеджа.
В ООП вам нужно описать базовый класс — Недвижимость, который будет хранить общие характеристики: что есть и у квартир, и у коттеджей. Класс Недвижимость, будет включать:

  • Площадь
  • Количество комнат
  • Тип дома
  • Цена

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

Далее мы создадим еще два класса: Коттедж и Квартира, оба будут наследовать все характеристики и методы класса Недвижимость и расширять его уникальными уже для себя свойствами и методами.

Класс Квартира, будет включать:

  • Этаж
  • Наличие балкона

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

Для класса Коттедж, будут выделены характеристики:

  • Количество этажей
  • Отопление
  • Приусадебный участок

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

Сценарий 1

Например, ваше начальство заинтересовалось продажей складов. У таких объектов недвижимости имеются специфические характеристики, по сравнению с любой другой недвижимостью:

  • Высота потолков
  • Устройство пола
  • Электроснабжение

ПП: Для нового объекта учёта, полностью с “нуля” создаётся всё новое и функции и форма.
ООП: Мы просто создаём новый класс Склад, наследуя всё необходимое от класса Недвижимость. В классе Склад, нам нужно будет только создать новые характеристики и методы для обработки новых данных.

Сценарий 2

Начальнику захотелось чтобы цена нового объекта недвижимости, с его идентификационным номером отправлялись к нему на мобильный. Он же должен быть в курсе происходящего.
Процедурное: Скрипя сердцем, идём меняем код во всех функциях и для квартир, и для коттеджей, и для складов. Везде добавляется код отправки смс на мобильный.
ООП: Улыбаясь, добавляем код отправки смс только в классе Недвижимость. Остальное, за нас делает принцип наследования.

Сценарий 3

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

Сценарий 4

Обнаружился баг в передачи смс с ценой, странным образом вместо шести нулей на конце, остаётся только один.
Процедурное: Ааааааа! Всё успокоились. Идём и исправляем код относящийся к каждому объекту недвижимости.
ООП: Наливаем себе любимый напиток, вдыхаем его аромат, и со спокойствием удава исправляем код одного метода в классе Недвижимость.

Заключение

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

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

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

Всё, что вам нужно знать из ПП

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

  • Модуль — это кусок программы, чаще всего занимающий целый файл, и представляющий собой набор программных объектов (тип данных, функция, конструкция, переменная, константа), относящихся к решению определённого круга задач. Например, существуют модули, работающие с графическими возможностями компьютера, другие занимаются отправкой почты и т.д.
  • Тип данных — это способ описания множества данных похожих друг на друга по своей структуре. Например, если вы хотите описать множество всех целых чисел со знаком, которые можно хранить, выдавая каждому по четыре байта, то для этого есть тип данных int.
  • Функция — законченный кусок программы (которому дано имя), решающий определённую подзадачу в вашей программе. Существуют встроенные функции, кроме них создаются новые для решения задачи. Встроенные функции часто связаны с элементарным вводом и выводом информации, преобразованием данных и т.д.
  • Конструкция — это специальная инструкция, изменяющая поток выполнения программы. Например: ветвления и циклы.
  • Переменная — реально существующий в программе представитель некоторого типа данных. Например: переменная, хранящая целое число, относится к типу int.
  • Константа — тоже самое, что и переменная, вот только значение в такой переменной не меняется.

Всё, что вам нужно знать из ООП

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

  • Класс — это прототип для создания похожих объектов, определяющий что будет в них храниться и какую функциональную нагрузку они будут нести. Данные и функции формулируются в понятиях, используемых для решения задачи. Обычно он создаётся в соответствии с некоторым паттерном, и сосуществуя в системе с другими классами должен находится с ними в слабой связи. Экземпляр класса иногда называют коротко — объект.
  • Данные — это полезная информация, характеризующая конкретного представителя данного класса, например: его цвет, размеры, форму и т.д. Их хранение осуществляется в переменных членах класса.
  • Методы — определяют функциональные возможности класса, а также выполняют служебную роль для данных класса. Реализуются в виде функций членов класса.
  • Параметры — специальные переменные, от которых зависит результат работы методов класса. Параметры появляются тогда, когда их данные нельзя передать через переменные члены класса. Например, в специальных методах, которые называются сеттеры (от слова “set” — установка), без параметров не обойтись, собственно именно через них данные попадают в экземпляр класса. Также данные могут попасть в объект через специальный метод конструктор — через его параметры.
  • Экземпляр — это конкретный представитель класса объектов, создающийся во время работы программы, с помощью конструктора (см. выше). Каждый экземпляр некоторого класса обладает одинаковым набором характеристик и поведением (набором методов). Отличием будет являться только разное значение этих характеристик.
  • Наследование — один из замечательных принципов ООП. Он описывает механизм выстраивания иерархии классов, позволяющий из одного класса создавать другой класс. Если бы его не было, представляете каким бы толстым оказался класс, в котором мы бы попытались описать множество всех компьютерных комплектующих? В результате, каждый экземпляр такого класса  тащил бы за собой ненужный шлейф из характеристик, которые принадлежат другим железкам. Например, у процессора болталось бы без надобности поле, хранящее разрешение монитора по горизонтали и вертикали. Но, у нас-таки есть принцип наследования! Мы можем создать нечто абстрактное — компьютерную железяку, которая обладает общими характеристиками и поведением всех железяк. И на основе её создать множество классов, которые уже будут содержать более специфические характеристики и поведение. Мы можем продолжать плодить классы, пока у нас не получится специальный класс, который будет описывать центральный процессор и не содержать ничего лишнего. Однако, учтите, что бы вы не сделали с родительским классом, это отразится на всех его потомках в любом “колене”.
  • Полиморфизм — ооо, это ооочень полезный принцип. Его сразу можно и не заметить, но когда вы начнёте использовать интерфейсы, вот тогдааа. Он описывает возможность создавать функции с одинаковым именем, но разным набором инструкций.
  • Инкапсуляция — вот с этим намного сложнее. Просто не совсем ясно, зачем называть то, что и так очевидно. Этот принцип говорит, что класс — это единое целое, включающее и данные и методы, которые могут обладать разным уровнем доступа из внешних ресурсов. Какие-то элементы класса доступны только внутри самого класса, до каких-то можно добраться где угодно. Главное — это “всё внутри”.

Понравилась статья? Посоветуйте другу


artanovy.com

Адаптированная образовательная программа в ДОУ

Как подготовить адаптированную образовательную программу?

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

Однако, чтобы принять такого ребёнка, детский сад должен обладать соответствующими ресурсами. Дети с особыми потребностями нуждаются в особых условиях. И это не только пандусы и лифты, не только среда, но и само образование должно быть доступным. Нельзя просто так привести ребёнка в коллектив и ждать, что он самостоятельно подхватит программу и начнёт показывать результаты.

Для того, чтобы разобраться, как подготовить детские сады к инклюзивному образованию, в декабре мы провели вебинар «Примерные адаптированные основные образовательные программы как условие повышения качества дошкольного образования».

Вебинар провела Анна Борисовна Теплова – кандидат педагогических наук, старший научный сотрудник лаборатории профессионального развития педагогики ФГБНУ «Институт изучения детства, семьи и воспитания «Российской академии образования».

Анна Теплова рассказала на вебинаре о том, как организовать инклюзивное образование в ДОУ, что включает в себя адаптированная основная образовательная программа (АООП) и чем она отличается от адаптированной образовательной программы (АОП).

Детским садам требуется перестройка

Инклюзивное образование предполагает создание специальных условий обучения, воспитания и развития детей с ОВЗ:

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

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

– Надо сказать, что несмотря на то, что всё это нам кажется пока новым, непреодолимым иногда, нам кажется, что всё это какие-то сложности, которые должны быть обеспечены, прежде всего, государством. На самом деле инклюзивное образование в России развивается. И закон, и стандарт на это работают. И поэтому говорить о том, что мы почему-то не готовы или всё это нужно спускать на тормозах, бессмысленно – инклюзивное образование в России есть и будет развиваться, – утверждает Анна Борисовна Теплова.

Проблемы становления инклюзии и пути решения

Однако развитие инклюзивного образования в России не обходится без трудностей. Надо сказать, что почти все здания старых проектов не подходят для детей-колясочников, даже если сделали пандус. К сожалению, на сегодняшний момент требуются серьёзные изменения в этих зданиях. Но это не единственная проблема, с которой сталкиваются школы.

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

Комментарий эксперта

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

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

Что такое АОП и АООП?

Дети с ОВЗ принимаются на обучение по адаптированной основной образовательной программе только с согласия родителей (законных представителей) и на основании рекомендаций психолого-медико-педагогической комиссии. Родители не обязаны приносить эти рекомендации в детский сад, но если они их принесли и согласны на обучение по АООП, то руководство ДОУ обязано эти рекомендации воплотить в жизнь.  

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

АОП и АООП: отличия

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

АОП и АООП – разные программы. Руководителям необходимо определить контингент детей и на основе особенностей этих детей разрабатывать адаптированные программы. В группах комбинированной направленности вместе с обычными детьми находятся дети с ОВЗ, поэтому необходимо рассматривать каждого ребёнка индивидуально – для каждого писать адаптированную образовательную программу. Для детей инвалидов соответственно обязательно составляется индивидуальная образовательная программа.

9 примерных АООП

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

На конец 2017 года было разработано и вынесено на обсуждение девять примерных адаптированных основных образовательных программ для разных категорий детей:

  1. для глухих детей;
  2. для слабослышащих детей;
  3. для слепых детей;
  4. для слабовидящих детей;
  5. для детей с тяжёлыми нарушениями речи и общим недоразвитием речи, с фонетико-фонематическим нарушениями речи;
  6. для детей с нарушениями опорно-двигательного аппарата
  7. для детей с задержкой психического развития;
  8. для детей с умственной отсталостью разной степени тяжести;
  9. для детей с расстройствами аутистического спектра.

Это впервые, чтобы для детей с РАС была разработана своя образовательная программа. Почему только сейчас, ведь педагоги работают с такими детьми уже много лет? Да, есть методические разработки, научные школы по работе с такими детьми, но научная школа и адаптированная программа для образовательной организации – это разные вещи. Дело в том, что перевести наработки учёных в практику образовательной организации оказалось достаточно сложно.

Эти программы ещё дорабатываются, так как не соответствуют некоторым положениям ФГОС и современным научным разработкам. К тому же, пока нет методических рекомендаций для практиков.

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

Пока эти девять примерных АООП не приняты, источниками для разработки адаптированных программ в ДОУ служат:

  • Федеральный закон ФЗ-273 «Об образовании в Российской Федерации»;
  • ФГОС ДО;
  • основная образовательная программа дошкольного образования;
  • примерная АОП ДО;
  • ОП ДО для детей с ОВЗ;
  • программно-методические и методические пособия для дошкольного образования;
  • авторские образовательные программы дошкольного образования.

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

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

  • для детей с тяжелыми нарушениями речи – 6 и 10 детей;
  • для детей с фонетико-фонематическими нарушениями речи в возрасте старше 3 лет – 12 детей;
  • для глухих детей – 6 детей для обеих возрастных групп;
  • для слабослышащих детей – 6 и 8 детей;
  • для слепых детей – 6 детей для обеих возрастных групп;
  • для слабовидящих детей, для детей с амблиопией, косоглазием – 6 и 10 детей;
  • для детей с нарушениями опорно-двигательного аппарата – 6 и 8 детей;
  • для детей с задержкой психического развития – 6 и 10 детей;
  • для детей с умственной отсталостью легкой степени – 6 и 10 детей;
  • для детей с умственной отсталостью умеренной, тяжелой в возрасте старше 3 лет – 8 детей;
  • для детей с аутизмом только в возрасте старше 3 лет – 5 детей;
  • для детей со сложным дефектом (имеющих сочетание 2 или более недостатков в физическом и (или) психическом развитии) – 5 детей для обеих возрастных групп;
  • для детей с иными ограниченными возможностями здоровья – 10 и 15 детей.

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

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

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

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

academy-prof.ru

Диагноз — Википедия

Материал из Википедии — свободной энциклопедии

Диáгноз (греч. διάγνωσις, лат. diagnosis «распознавание»; от dia «врозь» + gnosis «знание») — медицинское заключение о состоянии здоровья обследуемого, а также сущности болезни и состоянии пациента, выраженное в принятой медицинской терминологии и основанное на всестороннем систематическом изучении пациента. Процесс установления диагноза называется диагностикой. Медицинское обозначение: Ds.

Первоначальный диагноз может оказаться ошибочным; дополнительное обследование снижает вероятность ошибки диагностики[1].

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

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

  1. Имеются ли сопутствующие заболевания
  2. Наличие осложнений
  3. Основные симптомы и болезни
  4. Сочетание заболеваний

Алгоритм постановки клинического диагноза[править | править код]

  1. Расcпрос (анамнез)
    1. Жалобы пациента
    2. История болезни (лат. Anamnesis morbi)
    3. История жизни (Anamnesis vitae)
  2. Физические методы исследования
    1. Осмотр
    2. Пальпация
    3. Перкуссия
    4. Аускультация
      Предварительный диагноз
  3. Дополнительные методы обследования
    1. Лабораторные методы (анализы крови,

ru.wikipedia.org

Диагноз ооп – 404 Cтраница не найдена

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *