Как реализовать IXmlSerializable.ReadXml в случае использования AbstractFactory-Pattern и Полиморфизма - PullRequest
0 голосов
/ 29 января 2019

Я использую AbstractFactory и полиморфизм в своем проекте и мне нужно десериализовать xml до правильного типа в зависимости от xml-элемента под родителем.

Чтобы быть более конкретным (некоторый псевдокод дляобъяснение):

Public Interface IAnimal
              Inherits IXmlSerializable

   Public Property Name as String
   Public Property Age as Integer
   Public ReadOnly Property Type as AnimalType 'actually this is en Enum
End Interface

Public Interface IAnimalFactory
   Public Function Breed(animalType as AnimalType) as IAnimal
End Interface

Public Class AnimalFactoryImpl
             Implements IAnimalFactory
   Public Function Breed(animalType as AnimalType) as IAnimal
      Select Case animalType
         case ...
            return new Dog()
      End Select
   End Function
End Class

Public Mustinherit Class AnimalBaseImpl
                         Implement IAnimal
   'do all the general stuff common to all animals here

   Public MustOverride Sub Talk(words As String)

   'implement IXmlSerializable.ReadXml here
   'implement IXmlSerializable.WriteXml here
End Class

Public Class Dog
             Inherits AnimalBaseImpl
   'do dog specifics here
   'implement Talk() here
End Class

Public Class Cat
             Inherits AnimalBaseImpl
   'do cat specifics here
   'implement Talk() here
End Class

Public Class Cow
             Inherits AnimalBaseImpl
   'do cowspecifics here
   'implement Talk() here
End Class

XML, который мне нужен / имеет, выглядит как его

<animal>
   <animalType>Dog</animalType>
   <name>Snoopy</name>
   <age>62</age>   
</animal>

Легко реализовать метод WriteXml.Однако ReadXml вызывает у меня головную боль.

Пока что я включил код десериализации в родительский объект (например, Farm).Я прочитал все элементы внутри тега animal и затем вызвал animalFactory для создания правильного типа в зависимости от animalType.

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

Любые подсказки и трюки приветствуются: -)

1 Ответ

0 голосов
/ 30 января 2019

Хорошо, подумав немного, я сам придумал решение.Довольно просто, как только вы туда доберетесь; -)

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

Все, что мне нужно сделать, это передать объект XmlReader на фабрику и ожидать возврата того, что создает фабрика.

Чтобы остаться с приведенным выше примером кода:

Public Interface IAnimalFactory
   Public Function Breed(animalType as AnimalType) as IAnimal
   Public Function XmlDeserializeAnimal(reader As XmlReader) As IAnimal
End Interface

Public Class AnimalFactoryImpl
             Implements IAnimalFactory
   Public Function Breed(animalType as AnimalType) as IAnimal
      Select Case animalType
         case ...
            return new Dog()
      End Select
   End Function

   Public Function XmlDeserializeAnimal(reader As XmlReader) As IAnimal implements IAnimalFactory.XmlDeserializeAnimal
      'read all the tags here inkl. animalType
      Dim returnAnimal as IAnimal = Me.Breed(animalType)
      'set name and age here as per xml
      Return returnAnimal
End Class

Теперь это можно легко вызвать с помощью объекта контейнера (например, Farm), который также реализует IXmlSerializable.И все, что нужно знать классу контейнера, это IAnimalFactory и метод XmlDeserializeAnimal.

Скорее, если подумать (^ _ ~)

...