Как я получаю от привычки процедурного программирования и объектно-ориентированного программирования?

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

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

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

Но я хочу изменить! моим товарищам-программистам, помогите 🙂 какие-нибудь советы о том, как я могу вырваться из этой неприятной привычки?

Related of "Как я получаю от привычки процедурного программирования и объектно-ориентированного программирования?"

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

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

Примерно 13 лет назад я переключился на c ++ с c просто потому, что мне нужны идеи, но c нелегко выполнить. Короче говоря, моя потребность мотивировала мое программирование, ориентированное на объекты.

Объектно-ориентированный разум

Во-первых, у вас есть байты, символы, целые числа и поплавки.

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

Конгломерация данных

Так как информация о принтере должна иметь все свои переменные, заключенные в структуру принтера:

{id, name, location, impactType(laser|inkjet|ribbon), manufacturer, networkAddr}, etc. 

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

Включение информации

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

 {id, name, location, impactType(laser|inkjet|ribbon), manufacturer, networkAddr, *print(struct printer), *clean(struct printer) } 

Выпускники данных в информацию, когда данные содержат процессы обработки / восприятия данных.

Квантование информации

В настоящее время лазерные, ленточные и струйные принтеры не все имеют одинаковый набор информации, но все они имеют наиболее распространенный набор знаменателей (LCD) в информации:

Информация, общая для любого принтера: идентификатор, имя, местоположение и т. Д.

Информация найдена только в ленточных принтерах: usedCycles, лента (ткань целлофана), colourBands и т. Д.

Информация найдена только в струйной печати: чернильные картриджи и т. Д.

Информация найдена только в лазерах: …

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

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

Итак, ваши предпочтения / мотивация, ориентированные от объектов, говорят вам, что ваша жизнь программирования проще, если вы не используете объекты? То, что вы предпочитаете самостоятельно управлять всеми этими структурными сложностями. Вы не должны были писать достаточно программного обеспечения, чтобы чувствовать это.

Необходимость лени

Некоторые люди говорят: необходимость – это мать творчества. (а также, Любовь к деньгам – это корень зла).

Но для меня и моих когорт – лень перед необходимостью – родители творчества. (а также отсутствие денег – другой родитель зла).

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

Шаг 1. Прочтите хорошую книгу «Шаблоны дизайна». http://www.oodesign.com/

Шаг 2. Выберите то, что вы уже знаете, и переработайте его с точки зрения ОО. Это подход Code Dojo. Возьмите проблему, которую вы уже понимаете, и определите классы объектов.

Я сделал это – и записал, что я сделал.

См. http://homepage.mac.com/s_lott/books/oodesign.html#book-oodesign

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

Мнение OO основано на принципах, которые лежат на гораздо более базовом уровне, чем шаблоны проектирования. Модели дизайна как-то модно в наши дни (и на какое-то время), и они полезны, но это всего лишь еще один слой, который вы можете наложить на более простые вещи, которые вы должны обязательно изучить и освоить, если вы хотите правильно выполнять OO , Другими словами: вы можете отлично выполнять OO без шаблонов проектирования. Фактически, многие из нас делали OO задолго до того, как фраза «шаблоны дизайна» была даже придумана.

Теперь есть вещи, с которыми вы не можете обойтись. Я предлагаю вам начать с основ. Прочтите и поймите «Объектно-ориентированное программное обеспечение» 2-го издания Бертран Майер . Это, вероятно, лучшая книга по программированию OO вокруг, как по ширине, так и по глубине. То есть, если вы заинтересованы в программировании .

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

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

Опять же, я соглашусь со всеми рекомендациями по шаблонам проектирования. В частности, я бы рассмотрел шаблон MVC (Model-View-Controller), поскольку этот, возможно, самый простой способ понять. Вы уже написали код, чтобы вы могли смотреть на свои существующие приложения и начинать вкладывать каждую часть в категории M, V или C.

Удачи и получайте удовольствие!

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

Из многих концепций объектно-ориентированного программирования основной, который будет держать вас в курсе как новичок, – это инкапсуляция. Мой класс знает, как позаботиться о себе? Есть ли у моего класса поведение? Если это не так, то у вас нет класса, у вас есть структура, и вы, вероятно, будете писать много процедур для изменения своего состояния (как сказано, «вы вернулись к написанию C в Java») , Мой класс только публично раскрывает методы, которые необходимы для его использования? Эти вопросы, возможно, не могут быть тщательно проработаны, но, возможно, рассмотрим этот мысленный эксперимент при разработке ваших классов: что делать, если каждый из классов вашего приложения должен разрабатываться и поддерживаться другим разработчиком в Интернете, а классы также должны взаимодействовать с каждым из них интернет. Согласятся ли каждый разработчик, что класс, который они пишут и поддерживает, придерживается принципа единой ответственности и поэтому должен быть счастлив, что они не поддерживают то, что должно быть кем-то из кода elses?

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

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

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

В общем, это действительно помогает видеть вещи в контексте, прежде чем читать и практиковать их, поскольку это дает вам моменты, чтобы сказать себе: «О, вот почему они это сделали!» По крайней мере, так оно и работает для меня.

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

 "Put stuff together that changes together." 

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

Это также известно как «Изменение скорости».

Если вы будете следовать этому руководству, ваш код, естественно, будет развиваться в направлении хорошего дизайна OO. Зачем?

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

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

Аналогично, если класс имеет две части, которые изменяются одинаково часто, но в разное время или в разных направлениях (то есть по разным причинам), то это снова предлагает рефакторинг класса.

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

Я наткнулся на эту концепцию на C2 wiki много лет назад , но я редко видел, что она использовалась с тех пор. Мне это очень полезно. Он выражает некоторую важную основную мотивацию объектно-ориентированного проектирования. Конечно, это так ослепительно очевидно.

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

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

PS: другим принципом, которым вы должны следовать, является «Закон Деметры», то есть объект должен говорить только со своими друзьями. Друзья: сами, переменные экземпляра, параметры, местные жители и члены дружественных коллекций, но не глобальные и статические переменные.

Вы можете использовать подход карты CRC (Class / Responsibility / Collaboration) к дизайну OO. Это не слишком страшно – просто способ разобраться, какие должны быть ваши объекты, и какой объект должен отвечать за какие задачи, записывая материал на кучу карточек файлов, чтобы помочь прояснить ваши мысли.

Он был первоначально разработан как учебный инструмент для мысли OO и может работать для вас. Оригинальная статья находится по адресу: http://c2.com/doc/oopsla89/paper.html.

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

а) у вас может не быть свободного времени, чтобы выучить новый язык. Если да, то отлично.

б) Я преподавал университетский курс по программированию ОО с использованием Smalltalk, и студенты отлично справились с этой старой шуткой о том, как «вы можете писать FORTRAN на любом языке».

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

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

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

Я думаю, вам следует убедить себя, исследуя все недостатки с процедурным программированием, например (некоторые ключевые слова следуют, следите): scope, state … Практически вы сможете извлечь много терминов, просто прочитав примеры шаблонов проектирования (читайте: общие примеры использования объектов вместе.)

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

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

Посмотрите, как это работает для вас.

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

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

На самом деле ООП – это простой предмет, который становится значительно сложным. К сожалению, в C ++ у него много проблем, но действительно важны простые виртуальные методы. Чистые виртуальные базовые классы, используемые так же, как объект интерфейса Java, являются самыми полезными, но и просто виртуальными методами здесь и там пригодится.

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

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

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

Не.

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

Теперь, когда вы знаете, какие объекты, вы увидите, что объекты не найдены в коде. Они находятся во время выполнения; в пространстве между машиной и сознанием пользователя. Это то, что означает объектная ориентация. К сожалению, недавние научные круги превратили его в инженерную концепцию. Ничто не может быть дальше. И попробуйте, чтобы они могли подражать, конечный результат – дерьмо. Зачем? Потому что парадигма «ООП», известная сегодня в отрасли, построена на фундаментально ошибочной идее: декомпозиционный анализ идентичности. Как это порочит? Потому что само по себе лишено смысла. Это недействительно. В математическом смысле, в философском смысле. Это не то, как человек воспринимает и взаимодействует с миром.

Canon: Алан Кей, Трюгве Реенскауг, Джеймс (Джим) Коплиен

Как бы я хотел, чтобы я был на твоем месте. 🙂

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

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

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

Это очень трудоемко, и вам нужно сначала изучить основы ООП (у S.Lott есть отличные ссылки в другом ответе). Постоянный рефакторинг и множество «Doh!» моментом является правило; но я нашел это отличным способом изучения модульного программирования, потому что все, что я делал, сразу же стало заметным при реализации одного из проектов.

Просто практикуй. Если вы прочитали все о ООП и знаете что-то о ООП, и вы знаете принципы ООП, реализованные на вашем языке PHP … затем просто практикуйте, практикуйте и практикуйте еще кое-что.

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

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

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

  1. Я считаю, что механики ООП кажутся совершенно произвольными и не имеют никакого смысла, пока вы не прочитаете книгу о шаблонах проектирования и не поймете «почему». Я рекомендую Head First Design Patterns. Я думал, что ООП был смешным и совершенно бесполезным, пока я не взял эту книгу и не увидел, на что она действительно хороша.

  2. OO дает больше смысла, когда вы понимаете указатели на функции и как они связаны с косвенными вызовами функций и поздним связыванием. Поиграйте с указателями функций на C, C ++ или D на некоторое время и получите представление о том, для чего они предназначены и как они работают. Часть полиморфизма / виртуальной функции OO – это еще один слой абстракции поверх этого.

  3. Процедурный является правильным инструментом для некоторых рабочих мест. Не поступай так, как будто это неправильно. ИМХО все три основные парадигмы (процедурные, ОО, функциональные) ценны даже на мелкозернистом уровне в рамках одного модуля . Я предпочитаю:

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

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

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