Следующий уровень абстракции - сделать обнаружение и создание сообщений динамическими.Это часто достигается путем привязки имени строки к каждому сообщению или использования имени класса в качестве идентификатора.Вы можете использовать Reflection для обнаружения доступных типов сообщений, сохранять их в словаре и предоставлять экземпляры по имени.Это может быть дополнительно расширено, чтобы вводить сообщения из динамически загружаемых сборочных модулей с соответствующими метаданными и интерфейсами, чтобы обеспечить слабосвязанную композицию между различными сообщениями и потребителями сообщений.Когда вы дойдете до этого уровня, я рекомендую изучить такие структуры, как MEF , которые автоматизируют процесс обнаружения и внедрения экземпляра.
Для вашего простого приложения, я думаю, ваш подход уже достаточно чист.Серия операторов if или переключение работает просто отлично, и их легко понять / поддерживать, если у вас относительно небольшой и стабильный набор случаев.
Подводя итоги дальнейшего обсуждения в комментариях:
Основной проблемой при создании проблемы было то, что различные конкретные сообщения, унаследованные от Message, и, тем не менее, базовое Сообщение необходимо было создать, прежде чем более конкретные сообщения могли выполнить дальнейший анализ.Это неясно, предназначено ли Сообщение для того, чтобы содержать необработанную информацию или действовать как базовый тип для интерпретируемых сообщений.Лучшим дизайном является разделение функциональности RawMessage на собственный класс, четко разделяющий проблемы и устраняющий ощущение «создания экземпляра дважды».
Что касается рефакторинга с DTO и классом сопоставления:
Iна самом деле предпочитают ваш подход для кодирования / декодирования сообщений для конкретного приложения.Если я хочу отследить, почему FactoryTakenOverByRobotsMessage содержит недопустимые данные, для меня имеет смысл, что метод парсера для сообщения содержится в декодированных данных для сообщения.Где все становится более рискованным, если вы хотите поддерживать разные кодировки, как сейчас, вы начинаете хотеть декларативно указывать DTO (например, с атрибутами) и разрешать вашим различным транспортным уровням решать, как сериализовать / десериализовать.Тем не менее, в большинстве случаев, когда я использую ваш шаблон, это для конкретного приложения, часто с несовместимыми форматами сообщений и различными проприетарными кодировками, которые не отображаются должным образом каким-либо автоматическим способом.Я всегда могу использовать декларативное кодирование параллельно с проприетарной кодировкой в своем классе и выполнять сериализацию своих сообщений в XML для целей отладки.