Как перейти от плохого ООП-дизайна к хорошему?

Я много читаю о хороших и плохих методах проектирования ООП. Приятно знать, что ваш дизайн плохой или хороший. Но как перейти от плохого дизайна к хорошему? Я отделил интерфейс (xaml) и программный код от основного класса businesslogic. Этот последний класс растет. Я пробовал разделить его на более мелкие классы, но сейчас застрял. Есть идеи, как разбить большие классы? Основной класс имеет 1 список данных разных типов. Я делаю расчеты как в целом, так и по отдельным типам. У меня есть методы для выполнения этих вычислений, которые вызываются из событий, обрабатываемых в выделенном коде. Есть идеи, что делать дальше?

Дополнительная информация:

Мы уже около 6 месяцев в этом проекте. Я много лет работал с объектно-ориентированными языками (сначала C++, java, а теперь C#), но никогда не работал над таким большим проектом, как этот. Я считаю, что вначале мы сделали несколько неправильных поворотов, и я думаю, что нам нужно их исправить. На данный момент я не могу указать какие-либо подробности по этому проекту. Я собираюсь заказать одну-две книги по дизайну. Если я разделю все классы, как мне соединить их вместе? Может быть, даже лучше продолжить этот путь до первого релиза и после этого пересобрать части для второго релиза?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
0
2 330
12
Перейти к ответу Данный вопрос помечен как решенный

Ответы 12

Практикуйтесь и читайте. Повторить :)

Некоторые рекомендуемые книги:

  • Чистый код Роберта Мартина
  • Шаблоны проектирования GoF
  • Рефакторинг Мартина Фаулера

Лично мне также нравятся шаблоны дизайна Head First, но этот стиль может быть не для всех. Есть похожая книга под названием C# 3.0 Design Patterns (см. Ora.com). В нем много того же самого, но в более традиционной манере.

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

Bill K 14.01.2009 00:28

Я согласен - умение распознавать запахи кода очень ценно.

Brian Rasmussen 14.01.2009 08:56

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

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

Обновлено: перенесите это мышление на уровень «метода» - сделайте свои методы ответственными за одно и только за одно. Помогает очень быстро разбивать большие (> 50 строк) методы на многократно используемые фрагменты кода.

Я хочу разделить обязанности, но у меня есть так много методов, которые зависят друг от друга. Небольшие методы, за исключением нескольких +/- 50 лайнеров, все 10 строк или меньше.

Sorskoot 13.01.2009 23:48

Можете ли вы сгруппировать эти небольшие методы в несколько категорий?

Rob 14.01.2009 00:26

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

Sorskoot 14.01.2009 01:08

Проголосовал за Code Complete ref. Распределение ответственности является ключевым. Вы также можете посмотреть ПОНЯТЬ от Крейга Лармана. Кроме того, я считаю, что основательный объектно-ориентированный анализ является частью успешного объектно-ориентированного дизайна.

Fuhrmanator 13.04.2012 16:35

Рефакторинг Мартина Фаулера - отличная книга о том, как изменить дизайн вашего программного обеспечения, не нарушая его.

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

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

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

То же самое и "Рефакторинг под паттерны."

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

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

Измените то, как вы думаете об объектах. У каждого объекта должна быть одна очень конкретная ответственность. Если у вас есть класс с общим названием, например «MainBusinessLogic», вы, вероятно, делаете что-то не так.

Отличное место для начала: прочитайте Объектное мышление Дэвида Уэста.

Формулировка «ответственность» немного двусмысленна.

Joe Phillips 13.01.2009 23:23

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

Sorskoot 13.01.2009 23:38

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

goofballLogic 02.03.2010 01:41
Ответ принят как подходящий

The main class has 1 list of data of different types. I'm doing calculations on the total, but also on the individual types. I've got methods to perform these calculations which are called from events handled in the codebehind. Any ideas where to go from here?

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

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

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

Мне нравится идея переместить список в класс списка. Я должен изучить структуру состояний.

Sorskoot 13.01.2009 23:43

Это просто дополнение к некоторым прекрасным книжным предложениям.

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

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

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

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

Ориентация на дизайн может быть сложной задачей. Считайте умение кодировать похожим на спортивные способности. Большинство из нас играет на подъездных дорожках, некоторые - в местных спортивных командах. Сделать хороший предварительный дизайн для сложного проекта - задача игрока национальной лиги, он один на миллион. Примите это и планируйте изменения - итерации - ваш друг. (Между прочим, большинство из нас легко ДУМАЕТ, что мы на уровне штата. Это не так).

Извините за придирки, но разве вы не имеете в виду классы или типы, а не объекты?

Brian Rasmussen 14.01.2009 00:06

Да, у меня расстройство, из-за которого я иногда использую родственные термины в разговоре. (Хм, интересно, есть ли такая вещь! Если есть, все равно она у меня есть - а если нет, то ее надо назвать моим именем)

Bill K 14.01.2009 00:23

В дополнение к рекомендации Брайана о Чистый код Роберта Мартина, вы можете прочитать о «Твердые принципы объектно-ориентированного дизайна дяди Боба».

Вы можете услышать, как он говорит о принципах SOLID на Подкаст Hanselminutes 145 и чистом коде на .NET Rocks! Шоу # 388. На .NET Rocks! Шоу # 410 с ним также есть больше, но то, о чем он говорит, на самом деле не связано с вашим вопросом, я просто включил его на случай, если вам понравились первые два.

Из трех подкастов я предпочел «Гензельминуты».

Мне просто нравятся оба этих шоу. Я сейчас слушаю .net Rocks # 410 :)

Sorskoot 14.01.2009 01:04

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

По сути, мой подход состоит в том, чтобы иметь как можно меньше классов, но не меньше.

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

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

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

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

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

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

Просто моя приманка против ...

Я рекомендую Feather's Эффективная работа с устаревшим кодом, доступный и доступный для поиска на Сафари, а не на Рефакторинг. Он полон полезных и чутких глав, таких как У меня мало времени, и я должен его изменить и Мое приложение не имеет структуры..

Перспективы для рассмотрения:

  1. Автоматизация тестирования качества дизайна - ищите инструменты, которые предоставляют показатели качества дизайна в качестве перекрестной проверки ваших проектных решений.
  2. Возможность тестирования кода - помогает ли какой-либо из ваших рефакторингов или мешает разработке через тестирование, написанию модульных тестов или написанию функциональных тестов? Насколько сложно будет тестировать большие части архитектуры после интеграции?
  3. Обоснование - как вы защищаете эти решения, как от циничного CYA до руководства, так и, что более важно, чтобы ваша команда поверила в редизайн. Можете ли вы легко и последовательно объяснить Зачем, что изменение было внесено, и будет ли это объяснение легко найти через 6 месяцев?

Личные предпочтения в дизайне, особенно рефакторинге:

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

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

Другие вопросы по теме