Green-sell.info

Новые технологии
2 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Объектно ориентированное программирование для чайников

10 принципов ООП, о которых стоит знать каждому программисту

  • Переводы, 21 мая 2019 в 10:17
  • Klara Oswald

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

Принцип единственной ответственности (SRP)

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

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

Принцип открытости/закрытости (OCP)

Соответствует букве O акронима SOLID. Принцип можно выразить так: «Классы, методы или функции должны быть открыты для расширения (добавления новой функциональности) и закрыты для модификации». Такой подход запрещает кому-либо изменять уже опробованный и протестированный код, а значит, он не ломается. В этом и состоит основное преимущество такого подхода.

Ниже приведён пример кода на Java, который нарушает этот принцип:

А вот пример после рефакторинга. Теперь соблюдается принцип открытости/закрытости: при добавлении новой реализации Shape не нужно менять код GraphicEditor .

Принцип подстановки Барбары Лисков (LSP)

Соответствует букве L акронима SOLID. Согласно этому принципу подтипы должны быть заменяемыми для супертипа. Другими словами, методы или функции, работающие с суперклассом, должны иметь возможность без проблем работать также и с его подклассами.

Ивент переехал в онлайн, есть новые даты ( 14 – 15 июля ) , Москва и онлайн, 10 750–138 000 ₽

LSP тесно связан с принципом единственной ответственности и принципом разделения интерфейса.

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

Ниже приведён пример такого кода на Java:

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

Принцип разделения интерфейса (ISP)

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

В основном это происходит, когда один интерфейс содержит несколько функциональностей, и клиенту нужна только одна из них, а другие — нет.

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

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

Принцип инверсии зависимостей (DIP)

Соответствует букве D акронима SOLID. Прелесть этого принципа проектирования в том, что любой класс легко тестируется с помощью фиктивного объекта и проще в обслуживании, потому что код создания объекта централизован, а клиентский код не перегружен им.

Ниже приведён пример кода Java, который нарушает принцип инверсии зависимости:

Пример демонстрирует, что AppManager зависит от EventLogWriter . Если вам нужно использовать другой способ уведомления клиента (например push-уведомления, SMS или электронную почту), необходимо изменить класс AppManager .

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

Теперь перейдём к принципам, которые не входят в пятёрку SOLID, но не менее важны.

DRY (Don’t Repeat Yourself)

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

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

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

Инкапсуляция изменяющегося кода

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

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

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

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

Композиция вместо наследования

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

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

«Effective Java» Джошуа Блоха также советует отдавать предпочтение композиции вместо наследования. Если вы всё ещё не уверены, вы также можете посмотреть здесь, чтобы узнать, почему композиция лучше, чем наследование для повторного использования кода и его функциональности.

Программирование для интерфейса

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

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

Это также рекомендовано во многих книгах по Java, в том числе в Effective Java и Head First design pattern.

Ниже приведён пример для интерфейса в Java:

Принцип делегирования

Не делайте всё самостоятельно, делегируйте это в соответствующий класс. Классическим примером этого принципа являются методы equals() и hashCode() в Java. Если нужно сравнить два объекта, это действие поручается соответствующему классу вместо клиентского.

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

Заключение

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

Руководство по ООП на PHP

Мы рассмотрим такие понятия, как объектно-ориентированное программирование, классы PHP , конструкторы PHP , деструкторы PHP , магические методы PHP и т.д. Это руководство предназначено для начинающих и опытных программистов, которые хотят изучить PHP ООП , начиная с базового уровня.

Одним из самых значительных изменений в PHP 5 является наличие полностью объектной модели, которая позволяет повысить производительность. К одним из важных новых функций, добавленных в PHP 5 , относятся окончательные и абстрактные методы, классы, интерфейсы, клонирование и магические методы. Мы рассмотрим в данном руководстве ООП PHP примеры применения каждого из них.

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

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

Что такое ООП на PHP?

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

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

Автомобиль является объектом. Он имеет атрибуты цвета, размера, веса и функцию перемещения. Любой объект без функционала будет бесполезным. В ООП программист использует объекты; каждый объект имеет некоторые атрибуты и функции. В целом программирование сводится к построению модулей с помощью объектов.

Простое определение объектно-ориентированного программирования:

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

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

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

Важные термины руководства по ООП на PHP:

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

Класс

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

Объект

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

Переменная-член

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

Функция-член

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

Конструктор

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

Деструктор

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

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

В PHP 5 ООП наследование – это процесс, при котором класс ( подкласс ) получает все атрибуты и функции другого класса (суперкласса).

Суперкласс

Также известен как базовый или родительский класс — наследуется одним или несколькими подклассами.

Подкласс

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

Полиморфизм

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

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

Одна из важнейших концепций объектно-ориентированного программирования. Данные и функции, которые работают с этими данными, связываются между собой и не видны другим функциям.

Абстракция

Абстракция означает, что детали реализации функций или классов не видны.

Перезагрузка

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

Классы и объекты:

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

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

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


Класс в PHP ООП — это план или шаблон, по которому устанавливается экземпляр класса, создается объект. После того, как был создан класс, мы можем создать столько объектов, сколько захотим. На рисунке, приведенном выше, из одного класса ( плана ) были созданы пять объектов ( домов ). Объект всегда будет соответствовать инструкциям, приведенным в классе, используемом для его создания.

Преимущества ООП на PHP:

  1. Улучшение архитектуры и более чистый код

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

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

  1. Простота в обслуживании и обновлении

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

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

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

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

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

Данная публикация представляет собой перевод статьи « PHP OOP Tutorial » , подготовленной дружной командой проекта Интернет-технологии.ру

Объектно-ориентированное программирование для чайников

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

Классы и объекты

Начнем с самого базового понятия, — класса. Класс, он же тип, чтобы не мучить, и не сбивать с толку формулировками, можно объяснить на примере: класс это Собака, либо Кошка , либо Мышка , — всё это классы. А вот Жучка , Мурчик и Микки-Маус , — это экземпляры классов Собака , Кошка , Мышка . Экземпляры классов еще называют объектами. Итак, — Жучка это экземпляр класса Собака , Мурчик , — экземпляр класса Кошка , а Микки-Маус , — экземпляр класса Мышка , другими словами объект. Класс — единственный и неповторимый. У вас могут быть классы очень похожие, как овчарка и доберман, но это всё равно разные классы, хоть и очень похожие. Класс представляет собой набор характеристик/свойств, которые описывают его состояние и действия/методы, которые он может выполнить. Например, — нас есть класс Овчарка, к числу её свойств можно отнести «возраст» и «кличку». Экземпляр класса может выполнять действия, описанные в классе (лаять, сидеть, лежать), а также содержит значения свойств класса (класс Овчарка имеет свойство «возраст», а объект Барбос имеет значение, — 3 года). Помимо свойств и методов, объект имеет собственное имя, не путать со свойством «кличка», вот как это может выглядеть:

Что означает, что у объекта « МояСобака », есть кличка, и эта кличка — Барбос . А бывает и такая ситуация:

Тут у нас объект « ХозяинСобаки », у которого свойство « имя » имеет значение « Василий », а отчество равно « Иванович ».
Похожим образом работают методы (действия) объектов, например:

Методы могут параметризироваться, например, мы знаем что метод «лаять» заданное количество раз:

Объект всегда должен быть создан. Класс существует как факт, то есть, всегда. Создание объекта выглядит в разных языках программирования по-разному, хотя чаще всего это выглядит так:

МояСобака = new Собака()

Так создается новый экземпляр класса Собака. Иногда он может параметризироваться дополнительной информацией, необходимой для объекта (зависит от реализации класса):

МояСобака = new Собака(«Барбос»)

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

Наследование, инкапсуляция, полиморфизм

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

Как видите здесь Корова (Cow) унаследовала функционал от Животного (Animal) , изменив реализацию метода draw (конкретизируя как корова на самом деле выглядит), и оставив реализацию метода eat() . Это и есть наследование. Теперь инкапсуляция. Сам по себе этот термин означает «сокрытие». Инкапсуляция, это способ сделать невозможным изменения критичных для работы класса свойств или вызова внутренних методов. Например у нас есть требование: каждое животное должно иметь кличку, и кличка, в течении его жизни не должна меняться. Самое правильное в таком случае это принимать кличку в качестве параметра конструктора (метода выполняемого при создании класса), и хранить его во внутреннем, сокрытом свойстве. Например так:

Вот это и есть инкапсуляция. Нет способа изменить кличку снаружи класса, и вы можете быть уверены, что в любом случае, кличка у экземпляра класса будет именно та, что была задана при создании. Ну а теперь полиморфизм. Это тут тоже начнем с примера. Добавим класс Sheep (овца) .

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

Данный пример будет случайным образом генерировать экземпляр Коровы и Овцы, и рисовать их.
Нужно сказать что данный пример не совсем «чистый» полиморфизм. Дело в том что полиморфизм подразумевает собой реализацию одного и того же интерфейса в разных классах. Объясню: если бы мы не реализовали метод draw() в одном из классов, у нас периодически возникала бы ошибка обращения к несуществующему методу, а в языках со строгой типизицией, ошибка бы возникала еще на стадии компиляции. Чтобы избежать подобных казусов, нужно использовать итерфейсы (interface):

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

Объектно-ориентированное программирование: на пальцах

Ста­тья не маль­чи­ка, но мужа.

Наста­ло вре­мя серьёз­ных тем: сего­дня рас­ска­жем про объектно-ориентированное про­грам­ми­ро­ва­ние, или ООП. Это тема для про­дви­ну­то­го уров­ня раз­ра­бот­ки, и мы хотим, что­бы вы его постиг­ли.

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

Обычное программирование (процедурное)

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

Напри­мер, в интернет-магазине может быть функ­ция «Про­ве­рить email». Она полу­ча­ет на вход какой-то текст, сопо­став­ля­ет со сво­и­ми пра­ви­ла­ми и выда­ёт ответ: это пра­виль­ный элек­трон­ный адрес или нет. Если пра­виль­ный, то true, если нет — то false.

Функ­ции полез­ны, когда нуж­но упа­ко­вать мно­го команд в одну. Напри­мер, про­вер­ка элек­трон­но­го адре­са может состо­ять из одной про­вер­ки на регу­ляр­ные выра­же­ния, а может содер­жать мно­же­ство команд: запро­сы в сло­ва­ри, про­вер­ку по базам спа­ме­ров и даже сопо­став­ле­ние с уже извест­ны­ми элек­трон­ны­ми адре­са­ми. В функ­цию мож­но упа­ко­вать любой ком­байн из дей­ствий и потом про­сто вызы­вать их все одним дви­же­ни­ем.

Что не так с процедурным программированием

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

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

Тут при­хо­дит продакт-менеджер и гово­рит: «Хочу, что­бы поль­зо­ва­тель точ­но знал, в чём ошиб­ка при вво­де элек­трон­но­го адре­са». Теперь вам нуж­но научить функ­цию выда­вать не про­сто true — false, а ещё и код ошиб­ки: напри­мер, если в адре­се опе­чат­ка, то код 01, если адрес спа­мер­ский — код 02 и так далее. Это неслож­но реа­ли­зо­вать.

Вы зале­за­е­те внутрь этой функ­ции и меня­е­те её пове­де­ние: теперь она вме­сто true — false выда­ёт код ошиб­ки, а если ошиб­ки нет — пишет «ОК».

И тут ваш код лома­ет­ся: все десять мест, кото­рые ожи­да­ли от про­ве­ряль­щи­ка true или false, теперь полу­ча­ют «ОК» и из-за это­го лома­ют­ся.

Теперь вам нуж­но:

  • либо пере­пи­сы­вать все функ­ции, что­бы научить их пони­мать новые отве­ты про­ве­ряль­щи­ка адре­сов;
  • либо пере­де­лать сам про­ве­ряль­щик адре­сов, что­бы он остал­ся сов­ме­сти­мым со ста­ры­ми места­ми, но в нуж­ном вам месте как-то ещё выда­вал коды оши­бок;
  • либо напи­сать новый про­ве­ряль­щик, кото­рый выда­ёт коды оши­бок, а в ста­рых местах исполь­зо­вать ста­рый про­ве­ряль­щик.

Зада­ча, конеч­но, реша­е­мая за час-другой.

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

Это назы­ва­ет­ся спагетти-код, и для борь­бы с ним как раз при­ду­ма­ли объектно-ориентированное про­грам­ми­ро­ва­ние.

Объектно-ориентированное программирование

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

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

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

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

Объ­ек­ты харак­те­ри­зу­ют­ся четырь­мя сло­ва­ми: инкап­су­ля­ция, абстрак­ция, насле­до­ва­ние и поли­мор­физм.

Инкап­су­ля­ция — объ­ект неза­ви­сим: каж­дый объ­ект устро­ен так, что нуж­ные для него дан­ные живут внут­ри это­го объ­ек­та, а не где-то сна­ру­жи в про­грам­ме. Напри­мер, если у меня есть объ­ект «Поль­зо­ва­тель», то у меня в нём будут все дан­ные о поль­зо­ва­те­ле: и имя, и адрес, и всё осталь­ное. И в нём же будут мето­ды «Про­ве­рить адрес» или «Под­пи­сать на рас­сыл­ку».

Абстрак­ция — у объ­ек­та есть «интер­фейс»: у объ­ек­та есть мето­ды и свой­ства, к кото­рым мы можем обра­тить­ся извне это­го объ­ек­та. Так же, как мы можем нажать кноп­ку на блен­де­ре. У блен­де­ра есть мно­го все­го внут­ри, что застав­ля­ет его рабо­тать, но на глав­ной пане­ли есть толь­ко кноп­ка. Вот эта кноп­ка и есть абстракт­ный интер­фейс.

В про­грам­ме мы можем ска­зать: «Уда­лить поль­зо­ва­те­ля». На язы­ке ООП это будет «пользователь.удалить()» — то есть мы обра­ща­ем­ся к объ­ек­ту «поль­зо­ва­тель» и вызы­ва­ем метод «уда­лить». Кайф в том, что нам не так важ­но, как имен­но будет про­ис­хо­дить уда­ле­ние: ООП поз­во­ля­ет нам не думать об этом в момент обра­ще­ния.

Напри­мер, над мага­зи­ном рабо­та­ют два про­грам­ми­ста: один пишет модуль зака­за, а вто­рой — модуль достав­ки. У пер­во­го в объ­ек­те «заказ» есть метод «отме­нить». И вот вто­ро­му нуж­но из-за достав­ки отме­нить заказ. И он спо­кой­но пишет: «заказ.отменить()». Ему неваж­но, как дру­гой про­грам­мист будет реа­ли­зо­вы­вать отме­ну: какие он отпра­вит пись­ма, что запи­шет в базу дан­ных, какие выве­дет пре­ду­пре­жде­ния.

Насле­до­ва­ние — спо­соб­ность к копи­ро­ва­нию. ООП поз­во­ля­ет созда­вать мно­го объ­ек­тов по обра­зу и подо­бию дру­го­го объ­ек­та. Это поз­во­ля­ет не копи­па­стить код по две­сти раз, а один раз нор­маль­но напи­сать и потом мно­го раз исполь­зо­вать.

Напри­мер, у вас может быть некий иде­аль­ный объ­ект «Поль­зо­ва­тель»: в нём вы про­пи­сы­ва­е­те всё, что может про­ис­хо­дить с поль­зо­ва­те­лем. У вас могут быть свой­ства: имя, воз­раст, адрес, номер кар­ты. И могут быть мето­ды «Дать скид­ку», «Про­ве­рить заказ», «Най­ти зака­зы», «Позво­нить».

На осно­ве это­го иде­аль­но­го поль­зо­ва­те­ля вы може­те создать реаль­но­го «Поку­па­те­ля Ива­на». У него при созда­нии будут все свой­ства и мето­ды, кото­рые вы зада­ли у иде­аль­но­го поку­па­те­ля, плюс могут быть какие-то свои, если захо­ти­те.

Иде­аль­ные объ­ек­ты про­грам­ми­сты назы­ва­ют клас­са­ми.

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

При этом внут­ри объ­ек­та мето­ды могут быть реа­ли­зо­ва­ны по-разному. Напри­мер, уда­лить товар — это выдать пре­ду­пре­жде­ние, а потом поме­тить товар в базе дан­ных как уда­лён­ный. А уда­лить поль­зо­ва­те­ля — это отме­нить его покуп­ки, отпи­сать от рас­сыл­ки и заар­хи­ви­ро­вать исто­рию его поку­пок. Собы­тия раз­ные, но для про­грам­ми­ста это неваж­но. У него про­сто есть метод «Уда­лить()», и он ему дове­ря­ет.

Такой под­ход поз­во­ля­ет про­грам­ми­ро­вать каж­дый модуль неза­ви­си­мо от осталь­ных. Глав­ное — зара­нее про­ду­мать, как моду­ли будут общать­ся друг с дру­гом и по каким пра­ви­лам. При таком под­хо­де вы може­те улуч­шить рабо­ту одно­го моду­ля, не затра­ги­вая осталь­ные — для всей про­грам­мы неваж­но, что внут­ри каж­до­го бло­ка, если пра­ви­ла рабо­ты с ним оста­лись преж­ни­ми.

Плюсы и минусы ООП

У объектно-ориентированного про­грам­ми­ро­ва­ния мно­го плю­сов, и имен­но поэто­му этот под­ход исполь­зу­ет боль­шин­ство совре­мен­ных про­грам­ми­стов.

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

А теперь про мину­сы:

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

Что дальше

Впе­ре­ди нас ждёт раз­го­вор о клас­сах, объ­ек­тах и всём осталь­ном важ­ном в ООП. Кре­пи­тесь, будет инте­рес­но!

Урок №112. Введение в ООП

Обновл. 31 Дек 2019 |

В уроке №10 мы определили объект в C++ как часть памяти, которая используется для хранения значений. Объект с именем называется переменной.

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

Так что же тогда является объектно-ориентированным программированием? Для лучшего понимания воспользуемся аналогией. Оглянитесь вокруг — везде находятся объекты: книги, здания, еда и даже Вы. Объекты имеют два основных компонента:

Свойства (например: вес, цвет, размер, прочность, форма и т.д.).

Поведение, которое они могут проявлять (например: открывать что-либо, делать что-то и т.д.).

Свойства и поведение неотделимы друг от друга.

Объектно-ориентированное программирование (сокр. «ООП») предоставляет возможность создавать объекты, которые объединяют свойства и поведение в самостоятельный союз, который затем можно многоразово использовать. Это приводит к созданию следующего кода:

Так не только читабельнее, но и понятнее, кем является объект ( you — Вы) и какое поведение вызывается ( driveTo — поездка). Вместо того, чтобы сосредоточиться на написании функций, мы концентрируемся на определении объектов, которые имеют чёткий набор поведений. Вот почему эта парадигма называется «объектно-ориентированной».

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

Обратите внимание, ООП не заменяет традиционные методы программирования. ООП — это дополнительный инструмент управления сложностью.

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

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

Курсы «C#.NET Developer»

Курсы «Java Developer»

Курсы «Frontend Developer»

Курсы «JavaScript Developer»

Курсы «Python Developer»

Курсы «Unity/Game Developer»

Поделиться в социальных сетях:

Глава №7. Итоговый тест

Комментариев: 17

«Объектно-ориентированное программирование (ООП) предоставляет возможность создавать объекты, которые соединяют свойства и поведения в самостоятельный союз, который затем можно многоразово использовать. Это приводит к созданию следующего кода: you.driveTo(work); «

( Это что универсальный код для всех случаев жизни ? )

» Так не только читабельнее, но и понятнее, кем является объект (you — вы) и какое поведение вызывается (driveTo — поездка). Вместо сосредоточения на написании функций, мы концентрируемся на определении объектов, которые имеют четкий набор поведений. Вот почему эта парадигма называется «объектно-ориентированной».

Эта фраза приведена вами в тексте . На каком языке она сформулирована ( для кого ?). И кто сможет понять что вы ей хотите сказать .
Прошу немножко по русски и для людей которые только осваивают само понятие ООП.

Еще раз спасибо за качественный перевод и оформление! У Вас прекрасный перевод, так все грамотно выглядит. Не могу нарадоваться, что нашла и подсела на Ваш сайт. Это лучшее, что я видела. Настолько все постепенно и по порядку, так грамотно составлены уроки, что, кажется, по другому невозможно все это объяснить и понять.
Дойдя до данной главы, сделала паузу для разнообразия на Страуструпа «Принципы и практика использования С++» — вот где каша и все в кучу((( Сначала покажут, через 5 страниц только объяснят. Это кошмар, хорошо, что я уже подготовлена Вашим сайтом. В начале книги совсем нет новой информации для меня (после Вашего сайта )
А здесь иногда происходит так: изучаешь урок, вроде все понятно, но мысль в голове — «к чему это? как это может использоваться?» — а в следующем или через 1-2 урока все встает на места и в новом материале все складывается. В этих уроках действительно все с нуля, подробно и без воды. Как вы откопали такое сокровище? Это просто диво дивное) Надеюсь, что у Вас получится перевести все уроки до конца!

Я иногда тоже удивляюсь, насколько всё последовательно. Текущая тема нужна для освоения последующей: уроки переплетаются не только между другими уроками текущей главы, но и между уроками соседних глав. Получается как в математике: если сегодня не разобрался с косинусами/синусами — завтра не разберешься с теоремами косинусов/синусов (как и в случае с теоремой Пифагора нужно знать, что такое катеты и гипотенуза).

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

Спасибо за ваш отзыв. Надеюсь хватит сил перевести уроки до конца

Этот урок по ООП создают ваши умельцы — которые или не хотят , или не могут донести ученикам то для чего нужен Class . Рассказывая об ООП нужно раскрыть не только содержимое ( привести программный код в примерах ), а объяснить людям механизм для чего нужен Class и как его использовать.
Из аналогии обычного программирования нужно сказать , что Class это то место где собираются подпрограммы — функции относящиеся к одной тематике — объекту, например Class Array — массивы данных ( подпрограммы обработки данных в массивах — вычисление среднего , сумм элементов, сортировки и т.п. ) .
Переменные в private: это фактически глобальные переменные которые объявляются для всех подпрограмм в классе ( они видны из любой подпрограммы данного класса ) — зти переменные в private являются параметрами класса .
Для того чтобы их настроить ( занести данные в эти переменные при конкретном обращении ) используетcя SET функция или функция с любым другим именем , которая заносит в переменные указанные в private конкретные значения – инициализирует параметры для одного конкретного объекта ( экземпляра класса).
Функционал get функций это обращение к каким либо подпрограммам обработчикам , которые производят любые вычисления и любые операции с использование данных в переменных private и возвращают результаты .
Так как данные в private видны из любой подпрограммы в данном классе Class , эти данные не нужно указывать каждый раз в параметрах при обращении к подпрограммам обработчикам , они уже имеются в параметрах – private.
За счет этого уменьшается объем кода программы.
Вот как то так , я бы сказал в видео по началу обучению ООП.

Сомневаюсь, что ваше объяснение будет понятным хотя бы для 30% новичков. То, что вы вместили здесь — детальне расписывается в каждом отдельном уроке этой главы.

Посмотрим будет ли мое объяснеие более понятным чем ваше . Может кто нибудь прокомментирует.

Добрый день, Владимир. Я программирую на С++ уже порядком 10 лет. Не принимайте близко к сердцу, но ваше объяснение слишком сумбурно и готов поспорить, что ни один новичок вообще ничего не поймет из сказанного.

Владимир Сергеевич, все вы правильно написали, но начинающему просто непонятно, конкретика будет в соответствующих уроках. Я сам недавно окончил 4-х месячные курсы С++(очень формальные, если бы не ravesli.com не знаю, что и делал бы). Можно было бы еще и наследование, композицию, агрегирование классов вспомнить, дружественные классы, шаблоны классов. Или вспомнить, что классы — модификация структур, пришедших из С и начать их сравнивать. Но сразу это не поймешь, требуется постепенность. В этих уроках есть постепенный переход от простого к более сложному. Поверьте, что когда вам надо делать лабораторную, а теорию вы получите только в следующем модуле — это не есть хорошо и не способствует усвояемости материала.

работаю программистом 2 года, пытаюсь учить своего младшего брата программированию по этим урокам, увидел ваш комментарий, для эксперимента сначала дал прочитать сам материал, потом ваш комментарий, он ничего не понял из того что вы написали, ваш коментарий это как «С++ за час»

Здравствуйте. Очень признателен за эту вводящую в ооп статью. Но всё же мне непонятно,то есть не могу постичь смысла в этом виде программирования. Чтобы объяснить что я имею в виду, и объяснить где я не понимаю, я приведу примеры. Я заранее искренне надеюсь на вашу помощь.
Итак, для меня понятно,что существует некий код,который понимает компилятор, код, который что делает, выполняет какую-то функцию. Достаточно знать каков код нужен для реализации чего то конкретного и программа работает. Это мне понятно. Не понятно ООП. Не понятно как объект,который мы создаем( к примеру кнопка, при нажатии которой, отправляется сообщение кому то) может что то делать,выполнять? Откуда компьютер знает как ему что то сделать? Мы просто пишем название объекта, пишем на английском что он делает и это всё работает? К примеру, я создаю объект,которой называю «кнопка» на английском, пишу на английском что она нажимается, и потом на этом же английском пишу просто банально что она отправляет сообщение кому то и всё? Так работает ооп? Будет она работать? Спасибо ещё раз за помощь.

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

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

Так как я только изучаю программирование и плюсы мой первый язык, то уроки Дениса Маркова + данный учебник по C++, наверное, лучшая комбинация в мире))

Спасибо и Вам за комментарий и что читаете

Спасибо Вам огромное за грамотные уроки!
Это лучший русскоязычный материал по плюсам с их нюансами из всего, что я находил.

Значит, будем продолжать

Спасибо большое от меня тоже) Я программирую в основном на си, нашёл много чего не знал на вашем сайте) Жду новых статей)

Спасибо, что читаете Буду работать далее.

Читать еще:  Программирование вопросы к экзамену
Ссылка на основную публикацию
Adblock
detector