Как перейти от плохого к хорошему ООП-дизайну?
-
22-07-2019 - |
Вопрос
Я много читаю о хороших и плохих практиках в ООП-дизайне.Приятно знать, что твой дизайн плох или хорош.Но как перейти от плохого дизайна к хорошему?Я разделил интерфейс (xaml) и codebehind из основного класса businesslogic.Этот последний класс становится все больше.Я пытался разделить его на более мелкие классы, но теперь я застрял.Есть какие-нибудь идеи о том, как разделить большие классы?Основной класс содержит 1 список данных разных типов.Я делаю расчеты не только для общего количества, но и для отдельных типов.У меня есть методы для выполнения этих вычислений, которые вызываются из событий, обрабатываемых в codebehind.Есть какие-нибудь идеи, куда идти дальше?
Дополнительная информация:
Мы уже около 6 месяцев занимаемся этим проектом.Я много лет работал с объектно-ориентированными версиями (сначала c ++, java, а теперь c #), но никогда над таким большим проектом, как этот.Я считаю, что вначале мы сделали несколько неправильных поворотов, и я думаю, что нам нужно это исправить.На данный момент я не могу уточнить какие-либо подробности по этому проекту.Я собираюсь заказать одну или две книги о дизайне.Если я разделю все классы, как мне склеить их обратно вместе?Может быть, даже лучше продолжить этот путь до первого выпуска и перестроить части после этого для второго выпуска?
Решение
Основной класс имеет 1 список данных Различные типы. я делаю расчеты по итогу, но и по отдельные типы. У меня есть методы выполнить эти расчеты, которые вызываются из событий, обработанных в отделенный код. Любые идеи, куда идти здесь?
Если существует много вычислений, основанных на содержимом списка, вы рассматривали возможность перемещения операций в настраиваемый класс списка? То же самое касается операций с конкретными типами, возможно, они могут жить внутри типов?
С точки зрения выполнения похожих, но разных операций над разными типами рассмотрите возможность использования шаблона состояния ( это заменяет операторы switch), что позволяет обрабатывать объекты единообразно.
Большая часть ООП заключается в отбрасывании подхода «сверху вниз» / микроуправления и в рассмотрении подхода «снизу вверх» / самодостаточности. Стоит помнить, что ни один из подходов не является «правильным» в изоляции. Создание поддерживаемого кода - это поиск разумного баланса, который требует много размышлений и обычно развивается через опыт.
Другие советы
Практикуйтесь и читайте.Повторяю :)
Некоторые рекомендуемые книги:
- Чистый код Роберта Си Мартина
- Шаблоны проектирования GoF
- Рефакторинг Мартина Фаулера
Лично мне также понравились шаблоны дизайна Head First, но этот стиль может подойти не всем.Есть похожая книга под названием Шаблоны проектирования C # 3.0 (см. ora.com).В нем почти все то же самое, но в более традиционной манере.
Я настоятельно рекомендую подобрать Code Complete . Это отличная книга, которая предлагает массу полезных советов по таким вопросам, как ваш.
Чтобы дать вам быстрый ответ на ваш вопрос о том, как разделить большие классы, вот хорошее эмпирическое правило: сделайте так, чтобы ваш класс отвечал за одну вещь и только за одну. Когда вы начинаете думать так, вы быстро можете определить код, который не принадлежит. Если что-то не принадлежит, выделите его в новый класс и используйте его из исходного класса.
Изменить. Примите это мышление к методу " метод " уровень тоже - сделайте ваши методы ответственными за одно и только одно. Помогает быстро разбить большие (> 50 строк) методы на куски кода многократного использования.
Измените способ, которым вы думаете об объектах. Каждый объект должен иметь одну очень конкретную ответственность. Если у вас есть класс с именем что-то общее, например " MainBusinessLogic " Вы, вероятно, делаете что-то не так.
Отличное место для начала: прочтите Дэвида Уэста Объектное мышление .
Это всего лишь дополнение к некоторым прекрасным предложениям книг здесь. Р>
Чем лучше я работаю в ОО, тем больше я, кажется, уменьшаю размер объекта. Это не так, как будто я собираюсь за маленький размер объекта или что-то еще, но это, кажется, происходит.
Сохранение их небольшой, единой ответственности, простой в использовании и понимании - все это важно. Каждый объект должен быть как можно ближе к пуленепробиваемому, проверять ваши параметры и никогда не позволять вашему объекту переходить в недопустимое состояние. Четко определите все действительные состояния в документации.
Каждый раз, когда вы создаете класс, создайте тест для этого класса. Он не только проверяет ваш код, но и заставляет вас использовать свой собственный дизайн. Всегда думайте о своем классе из этого «внешнего вида». Убедитесь, что вы не спрашиваете слишком много о человеке, использующем ваш класс, и все, что вы спрашиваете о нем, должно быть задокументировано в интерфейсе. Часто я просто добавляю быстрый класс в класс, если нет доступной среды тестирования - он помещает пример того, как использовать ваш код прямо в том же файле.
В кодировании почти все мое время тратится на выяснение того, что сделал кто-то другой. Если бы я мог просто выпустить код, используя известные или хорошо документированные API, моя работа была бы тривиальной, а графики значительно короче.
Дизайн первым может быть сложным. Считайте, что кодирование похоже на спортивное умение. Большинство из нас играют на подъездных дорожках, некоторые играют в местных спортивных командах. Сделать хороший предварительный дизайн для сложного проекта - задача игрока национальной лиги, они - один на миллион. Примите это и планируйте изменения - итерации - ваш друг. (Кстати, большинство из нас ДУМАЮ, что мы на государственном уровне легко. Мы не).
В дополнение к рекомендации Брайана о Чистом коде Роберта С. Мартина , вы можете прочитать о " Дяде Бобе " ТВЕРДЫЕ Принципы объектно-ориентированного проектирования .
Вы можете услышать, как он говорит о принципах SOLID на Hanselminutes Podcast 145 .NET Rocks! Шоу № 388 . С ним также можно познакомиться в .NET Rocks! Покажите # 410 , но то, о чем он говорит, на самом деле не связано с вашим вопросом, я просто включил его на тот случай, если вам понравились первые два.
Из трех подкастов я предпочел Hanselminutes.
Рефакторинг Мартина Фаулера - отличная книга о том, как изменить дизайн вашего программного обеспечения, не нарушая его.
Шаблоны проектирования работает аналогично алгоритмам, но рассказывает, как объединять объекты выполнять различные полезные задания.
Наконец, у Мартина Фаулера есть множество полезных шаблонов проектирования для приложений. Например, Пассивное представление
Я обнаружил, что работать над сложным «заданием» без посторонней помощи, а затем увидеть, как кто-то другой это сделал, было большим опытом для меня.
В частности, одним из заданий было создание программы, подобной банковской, в которой мы должны были отслеживать транзакции и иметь возможность рассчитывать заработанные проценты и тому подобное. Это действительно была моя первая ООП-программа, и очень хорошая из-за своей сложности. Это становится слишком запутанным (для начинающего), чтобы делать это в линейном стиле без ошибок.
Я могу сказать только то, что работает для меня, и я действительно не нашел никого, кто работает таким же образом, поэтому я не уверен, поможет ли это вам очень сильно.
По сути, мой подход состоит в том, чтобы как можно меньше классов, но не меньше.
Во-первых, единственное время, когда вам нужно сохранить информацию, - это если вы получаете ее в момент времени A и нуждаетесь в ней позже B. Если вы получаете ее и работаете с ней одновременно, возможно, в этом нет необходимости. хранить его.
Во-вторых, что ты с этим делаешь? Если вы собираетесь выполнять итерацию через определенные упрощенные способы, вы можете думать о нем как о наборе инструкций, а программа, которая работает с ним, как об интерпретаторе набора инструкций. В этом случае вам может понадобиться разработать набор инструкций с байт-кодом с помощью интерпретатора и закодировать вашу информацию в этом наборе инструкций.
В-третьих, как часто меняется информация? Если некоторая информация меняется очень редко, вы можете использовать частичную оценку (например, генерацию кода). То есть вы берете редко меняющуюся информацию и используете ее для создания специальной программы, которая делает то же, что и ваша общая программа, с этой информацией, но гораздо быстрее. Генератор кода легко написать, потому что он имеет дело только с частью входной информации, частью, которая изменяется медленно.
Большая часть структуры данных, которую я вижу в эти дни, существует для поддержки пользовательского интерфейса. Это явно не содержит объекты, которые заботятся о пользователе, и в идеале вам не нужно заботиться. Поэтому я создал DSL для пользовательских интерфейсов, который скрывает все эти ухищрения.
Держитесь подальше от событий и уведомлений, если это возможно, потому что они происходят в моменты времени и, следовательно, представляют собой постепенные изменения в состоянии. Вам придется сильно волноваться по поводу того, что они могут быть уронены, продублированы или искажены. Часто они используются в теории о том, что простой стиль опроса будет «менее эффективным»; когда на самом деле часто происходит обратное.
Поэтому, когда я вижу, как люди зацикливаются на технологиях классов и т. д., обычно это происходит потому, что они занимаются слишком большой структурой данных.
Просто моя приманка ...
Я рекомендую Эффективную работу Feather с устаревшим кодом , доступную и доступную для поиска на Safari , через рефакторинг . Он полон полезных и чутких глав, таких как У меня мало времени, и я должен его изменить и Мое приложение не имеет структуры.
Перспективы для рассмотрения:
<Ол>Личные предпочтения в дизайне, особенно рефакторинг:
<Ол>Попробуйте написать больше тестируемого кода, это само по себе заставило меня исследовать и внедрять улучшенные методы ООП / концепции дизайна.