|
13 / 11 / 2
Регистрация: 07.05.2015
Сообщений: 418
|
|
Архитектура приложения, даункаст30.09.2021, 07:38. Показов 3097. Ответов 22
Метки нет (Все метки)
Предположим, я хочу создать класс "ящик с инструментами". В ящике могут лежать различные инструменты: ключи, молотки, пилы и т. д. Каждый инструмент наследуется от класса Tool. Ящик с инструментами хранит объекты типа Tool, чтобы в нём могли лежать объекты разных типов. Теперь я реализую объект "сортировщик инструментов", который берёт один за одним объект Tool из ящика и раскладывает их по ящикам "ящик с молотками", "ящик с ключами", "ящик с плоскогубцами"... Сортировщик не знает какой именно инструмент лежит в типе Tool. Допустимо ли здесь проверять каждый тип (операторы as, is) или есть какая-то более удачная архитектура/паттерн?
Добавлено через 56 минут Нашёл, что можно использовать паттерн visitor. Хорошее ли это решение?
0
|
|
| 30.09.2021, 07:38 | |
|
Ответы с готовыми решениями:
22
Архитектура приложения Архитектура приложения
|
|
1595 / 600 / 185
Регистрация: 05.12.2015
Сообщений: 970
|
|
| 30.09.2021, 14:18 | |
|
Модель объектов должна быть абстрактной и не привязана к типам .NET
Просто создаешь enum перечисление объектов например ToolType{none, i1,i2,i2} В базовом классе Tool виртуальное свойство например ToolType myType=>ToolType.none В каждом наследнике override myType=>ToolType.itemX Для ящиков создаешь базовый класс Box наследник Tool Для каждого типа ящика override myType При добавлении в ящик любой Tool просто сравниваешь совпадает его myType с типом ящика. myType также необходим для базы данных.
1
|
|
|
13 / 11 / 2
Регистрация: 07.05.2015
Сообщений: 418
|
||
| 30.09.2021, 14:28 [ТС] | ||
|
У меня появилось ещё больше вопросов, извините...
1) чем ваш пример отличается от as is с последующим даункастом? Мы же теперь идентификатор типа просто храним в другом месте... нет? 2)всё-таки уместен ли паттерн посетитель (visitor)? 3)
Я прошу прощения, что это сообщение выглядит так душно, просто я хочу разобраться. Большое спасибо за ответ
0
|
||
|
1595 / 600 / 185
Регистрация: 05.12.2015
Сообщений: 970
|
|||||||||||
| 30.09.2021, 16:32 | |||||||||||
Пройдите пошагово. Если Add вернул true значит добавил. Логика дальше ваша.
0
|
|||||||||||
|
304 / 186 / 45
Регистрация: 05.07.2018
Сообщений: 580
|
||||
| 30.09.2021, 20:45 | ||||
Box: ICollection<Tool>Aycon, OfType<> в LINQ, можете посмотреть в его сторону, скорее всего пригодится. Visitor ничем Вам не поможет в данном случае.
1
|
||||
|
13 / 11 / 2
Регистрация: 07.05.2015
Сообщений: 418
|
|
| 30.09.2021, 20:58 [ТС] | |
|
Я с помощью посетителя обошёл даункаст. Просто хочу узнать, хорошая ли это практика.
0
|
|
|
304 / 186 / 45
Регистрация: 05.07.2018
Сообщений: 580
|
|
| 30.09.2021, 21:03 | |
|
0
|
|
|
13 / 11 / 2
Регистрация: 07.05.2015
Сообщений: 418
|
||||||
| 30.09.2021, 21:35 [ТС] | ||||||
|
Что-то типа:
Круто же? Или так нельзя делать? Добавлено через 2 минуты LINQ мне не удобен, объекты лежат в дереве (Это не инструменты, инструменты - для примера)
0
|
||||||
|
601 / 485 / 185
Регистрация: 19.04.2016
Сообщений: 1,885
|
||||||
| 30.09.2021, 22:04 | ||||||
|
Зачем весь этот "Визитор", если свелось к...
0
|
||||||
|
304 / 186 / 45
Регистрация: 05.07.2018
Сообщений: 580
|
||||||||
| 30.09.2021, 22:05 | ||||||||
![]() Что если списки заполнять прямо в методах Visit<...>:
1
|
||||||||
|
13 / 11 / 2
Регистрация: 07.05.2015
Сообщений: 418
|
|||||||
| 30.09.2021, 22:14 [ТС] | |||||||
|
Эта проверка безопасна в смысле:
Если есть класс Point и от него наследуется Point2D от которого наследуется Point3D, то прямая проверка на тип объекта Point3D запнётся и даст true ещё на проверке принадлежности классу Point. А Visitor даст однозначный ответ. Согласны? Добавлено через 45 секунд Поэтому здесь typeof уместен и однозначен Добавлено через 1 минуту Добавлено через 2 минуты Можно добавить в Visitor-а обычный enum и проверки вообще не будет. Ща покажу
0
|
|||||||
|
304 / 186 / 45
Регистрация: 05.07.2018
Сообщений: 580
|
||
| 30.09.2021, 22:21 | ||
|
0
|
||
|
13 / 11 / 2
Регистрация: 07.05.2015
Сообщений: 418
|
|
| 30.09.2021, 22:30 [ТС] | |
|
Ну как сказать... Каждый дочерний тип просто перегрузит метод Accept(Visitor visitor), а Visitor укажет конкретный тип. Ну и да, он будет иметь методы
VisitPoint(Point point); VisitPoint2D(Point2D point); VisitPoint3D(Point3D point); Перегрузка не протребовалась бы, полагаю) Но, спасибо за внимательность Добавлено через 1 минуту А, хотя да, вы правы) Он просто вызовет старший метод... Но с enum всё работает как положено)
0
|
|
|
304 / 186 / 45
Регистрация: 05.07.2018
Сообщений: 580
|
|||||||||||
| 30.09.2021, 22:31 | |||||||||||
0
|
|||||||||||
|
13 / 11 / 2
Регистрация: 07.05.2015
Сообщений: 418
|
|
| 06.10.2021, 12:52 [ТС] | |
|
Вопрос актуален, я предполагаю, что такой метод нарушает принципы Solid, а именно принцип инверсии зависимостей. При моём решении абстракция ITool зависит от деталей.
Поясняю: ITool зависит от класса IToolVisitor, который в свою очередь, зависит от конкретных классов - Hammer и Pliers. Отсюда следует, что ITool транзитивно зависит от Pliers и Hamer. Как решить парадокс правильно?
0
|
|
|
Модератор
|
||
| 07.10.2021, 10:55 | ||
|
1) Каждый тип "инструмента" требует своего ящика или есть какой-то набор ящиков? Во втором случае требуются правила по которым определить ящик для инструмента подходящего для нескольких. 2) Сортировка по ящикам должна происходить автоматически при добавление инструмента или набор ящиков возвращается как результат некоего меттода? Добавлено через 1 минуту 3) Типы инструментов заранее определены или нужно решение с учётом произвольного их расширения?
0
|
||
|
13 / 11 / 2
Регистрация: 07.05.2015
Сообщений: 418
|
|
| 07.10.2021, 11:16 [ТС] | |
|
1) У каждого инструмента свой ящик.
2) Нужен способ любой инструмент привести к его самому младшему потомку не нарушая Solid и ООП, не важно каким образом. У вас есть инструмент, вы не знаете наверняка, является ли он молотком и можно ли им стучать, но если это молоток - то забить гвоздь. Как работать с абстракцией ITool не завися от конкретного типа? 3) Нужно решение с учётом произвольного их расширения
0
|
|
|
Модератор
|
|||||||
| 07.10.2021, 11:36 | |||||||
|
Aycon, по интерфейсу Форума:
1
|
|||||||
|
Модератор
|
|||||||||
| 07.10.2021, 11:51 | |||||||||
Сообщение было отмечено Aycon как решение
РешениеВо втором случае нужен для хранения нужен не обычный лист, а коллекция с уведомлением об изменении. Возможно кастомная. Добавлено через 7 минут Пример получения такого словаря:
Значение словаря - список инструментов этого типа. Добавлено через 3 минуты И потом спокойно пользуйтесь LINQ.
0
|
|||||||||
|
13 / 11 / 2
Регистрация: 07.05.2015
Сообщений: 418
|
||
| 07.10.2021, 12:49 [ТС] | ||
|
Элд Хасп
Я привёл её в качестве проблемы архитектуры. Проблема в том, что вы не можете абстрагироваться от подклассов какой-нибудь абстракции (коей в данном Примере выступает интерфейс ITool). Я не могу использовать интерфейс вместо классов, его реализующих, поскольку этот интерфейс не декларирует возможности потомков, как в данном случае класс Hammer, который может забивать гвозди, в отличие от Pliers(плоскогубцы). Вопрос чисто фундаментальный, как я могу абстрагировать модуль высокого уровня от модулей низкого уровня через интерфейс, если интерфейс не даёт полного описания объектов, которые его реализуют? Как хорошие программисты решают эту задачу? Я только это хочу знать.
0
|
||
| 07.10.2021, 12:49 | |
|
Помогаю со студенческими работами здесь
20
При создании статического класса нарушалась вся архитектура приложения
Архитектура и проектирование приложения: ищу видео, статьи и книги с примерами реальных маленьких приложений Архитектура приложения Архитектура приложения Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
|
Оттенки серого
Argus19 18.03.2026
Оттенки серого
Нашёл в интернете 3 прекрасных модуля:
Модуль класса открытия диалога открытия/ сохранения файла на Win32 API;
Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
|
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога
Финальные проекты на Си и на C++:
finish-rectangles-sdl3-c. zip
finish-rectangles-sdl3-cpp. zip
|
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие.
Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
|
|
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ВВЕДЕНИЕ
Выполняя задание на управление насосной группой заполнения резервуара,. . .
|
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
|
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога
Финальные проекты на Си и на C++:
hello-sdl3-c. zip
hello-sdl3-cpp. zip
Результат:
|
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога
MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
|