Как вы подходите к дизайну классов в ООП?

12

Когда я пытаюсь разработать OO-решение, я обычно использую моделирование CRC, в котором я перечисляю имена классов (существительные), что они делают (глаголы) и как они взаимодействуют с другими классами.

Этот блог имеет следующее, что можно сказать об этом подходе существительное-глагол

   ...This approach, which I will call “noun and verb,” is so limited 
   I’ll dare to call it brain damaged....

Мой вопрос: существует ли лучшая техника моделирования для использования ОО подхода?

Винот Кумар СМ
источник
1
Предполагая, что ставка $$$ имеет смысл, просто начните кодировать. Застряв, найдите способ убрать препятствие (я). Рефакторинг позже. «CRC» - это не то, о чем я слышал раньше, но это не помешало мне писать уроки. Если бы существовал отличный механический принцип, кто-то сделал бы хороший инструмент для анализа кода, используя его, и он был бы популярен. Пока я не найду такую ​​вещь, я буду продолжать использовать свою интуицию. Конечно, нужно использовать глаголы и существительные в нужных местах ...
Иов
1
Иш. Просто получите быструю интеллектуальную модель системы и начните писать код. Я знаю, что многие здесь не согласятся со мной, но вы можете переанализировать этот материал до смерти. Пока у вас есть приличный опыт, вы не должны понимать, что будет, а что нет. Если с чем-то рано или поздно трудно работать, измените его, и теперь у вас есть еще больше опыта.
Эд С.

Ответы:

12

Справедливости ради, он добавил «В шутку» к этому требованию.

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

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

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

Но как только вы начинаете писать тесты, вы понимаете, какой объект является самым важным в любой игре: правила.

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

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

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

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

Может быть, у меня будет базовый класс MonopolyPiece, и каждый тип элемента будет производным от них. Я начну с DogPiece. Первый тест ... ааа. На самом деле здесь нет логики. Да, каждая часть будет нарисована по-разному, поэтому мне может понадобиться DogDrawer, но пока я заканчиваю игру, я просто хочу написать «D» на экране. Я приправлю интерфейс в конце.

Давайте найдем реальную логику для тестирования. Таких домов и отелей много, но тесты не нужны. Денег нет Имущественных карт нет. И так далее. Даже доска - не что иное, как конечный автомат, она не содержит никакой логики.

Вы быстро обнаружите, что у вас в руке осталось три вещи. Карты Chance и Community Chest, пара костей и набор правил. Это будут важные части для проектирования и тестирования.

Вы видели это, когда писали существительные и глаголы?

На самом деле, в «Образцах и практиках гибких принципов» Роберта Мартина есть замечательный пример, когда они пытаются реализовать приложение «Счетная карта для боулинга» с использованием TDD и находить все виды вещей, которые, по их мнению, являются очевидными классами, просто не заслуживают внимания.

прецизионный самописец
источник
Не могу понять, почему TDD является ответом на проведение ОО-анализа, о котором спрашивает ОП. Существительное / глагол является самым первым приближением проблемной области (наиболее полезно для начинающих), и, конечно, уточнение классов может быть выполнено позже, но утверждение, что TDD направляет проектирование в правильном направлении, ИМХО совершенно неверно (вы действительно предлагаете пропустить планирование , дизайн и начать кодирование ?!). Пример Monopoly также вводит в заблуждение, в зависимости от того, над какой частью системы вы работаете: пользовательский интерфейс или базовая логика. На стороне пользовательского интерфейса кубики и тому подобное имеют смысл.
Роман Суси
+1 и избранное. Во-первых, мой опыт показывает, что TDD быстро направляет ваш мыслительный процесс в нужные места (ну, вы можете иногда спорить о «быстро»). И это также может помочь выявить дефекты проектирования на ранней стадии: вы научитесь внедрять зависимости, если ничего больше! Существительное-глагол - кто здесь не начинается? Но большинство из этих объектов совершенно тупые. Данные, если хотите, глубоки. Название оригинальной книги говорит обо всем для меня Алгоритмы + Структуры данных = Программы
radarbob
3

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

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

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

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

Изменить: Просто прочитайте половину этого второго блога, и я должен сказать, что я согласен с этим довольно много. Мне придется прочитать остальное и посмотреть, что он предлагает с точки зрения обучения.

Эдвард Стрендж
источник
2
Ошибка: строка 2: недействительная гиперссылка!
Взломщик
1
Программное обеспечение SE скрыло это. При предварительном просмотре все работало нормально. Вот ссылка в текстовом виде: objectmentor.com/resources/articles/CoffeeMaker.pdf
Эдвард Стрендж,
0

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

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

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

Homde
источник