1

I'm using an AbstractFactory and polymorphism in my project and need to de-serialize xml to the correct type depending on a xml-element under the parent.

To be more specific (some pseudo code for explanation):

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

the xml that I need/have looks like his

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

It's easy to implement the WriteXml method. However, the ReadXml is giving me headaches.

So far I have included the de-serialization code in the parent object (e.g. Farm). I read all the elements from within the animal tag and then call animalFactory to create the correct type depending on the animalType.

I think that this is really not nice code and it really should go into the AnimalBaseImpl or the factory but I'm at a loss how to do this as new AnimalBaseImpl() is the first thing that will happen when de-serializing...

Any hints and trick welcome :-)

1 Answers1

0

OK, after thinking for a bit more I came up with the solution myself. Quite easy once you get there ;-)

Since I'm using the Factory Pattern it's the Factory that needs to implement the deserialization. This is a creational pattern after all. This means, that ALL the creation methods should go into that factory. And deserializing is a creation method.

All i need to do is pass the XmlReader object to the factory and expect a return of whatever the Factory creates.

To stay with the above code example:

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

Now this can easily be called from withing the container object (e.g. Farm) which also implements IXmlSerializable. And all the container class needs to know of is the IAnimalFactory and the XmlDeserializeAnimal method.

Rather straight forward if you think about it (^_~)