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

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

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

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

но я хочу измениться! к мои коллеги-программисты, помогите :) любые советы о том, как я могу вырваться из этой мерзкой привычкой?

20 ответов


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

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

около 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)
}

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

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

теперь лазер, лента и струйные принтеры не все имеют такой же набор информации но они все имеют наиболее распространенный набор знаменателей (ЖК) в информации:

Info общее к любому принтеру: id, имя, положение, etc

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

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

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

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

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

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

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

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


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

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

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

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

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


мышление ОО основано на принципах, которые лежат на гораздо более базовом уровне, чем шаблоны проектирования. Шаблоны дизайна как-то модны в эти дни (и были некоторое время), и они are полезно, но они просто еще один слой, который вы можете положить на более основные вещи, которые вы абсолютно необходимо учиться и осваивать Если вы хотите сделать OO правильно. Другими словами: вы можете сделать ОО совершенно без картин дизайна. На самом деле, многие из нас сделали OO задолго до фразы "узоры дизайна"были даже придуманы.

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


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

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

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

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


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

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

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

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


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

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


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

"Put stuff together that changes together."

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

Это тоже известный как "скорость изменения".

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

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

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

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

иногда заменить "class" на "метод." Например, если одна строка метод может измениться более чаще, чем остальные - возможно, это линия, которая создает новый объект экземпляр и содержит имя его class-рассмотрите возможность перемещения его в свой собственный обычный. Тогда подклассы могут легко измените их, переопределив.

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

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

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

PS:не глобальные и статические переменные.


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

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

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

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

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

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


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

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


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

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


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

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


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

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

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

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


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

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


нет.

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

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

Canon: Alan Kay, Trygve Reenskaug, James (Jim) Коплиен!--1-->

Как бы я хотел оказаться на твоем месте. :)


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

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


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

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


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

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


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


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


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

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

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

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

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

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