Home  /  Questions  /  Question



50   50
Sep 14, 2010


Factory Patterns... Abstract Factory, Factory Method, Simple Factory...

I have an object model specifically for seeing how I could implement the Factory patterns. I would like any comments or any alternatives or suggestions to improve on this design. I have a couple question below the code.

The model is simple enough and is a representation of a business phone. You have an agent login to participate in call distribution, ringer tone (ringtone) and phone properties. The high level structure is as follows:

Status:
- AgentStatus
- PhoneStatus
- RingerStatus

Namespace Factory

       Namespace Items

           Namespace Agent

               Public Enum States
                   available
                   unavailable
               End Enum

               Public Class AgentStatus

                   Dim _state As States
                   Public Property State() As States
                       Get
                           Return _state
                       End Get
                       Set(ByVal value As States)
                           _state = value
                       End Set
                   End Property

               End Class

               Public Class AgentStatusFactory
                   Public Shared Function Parse(ByVal status As System.Xml.Linq.XElement) As AgentStatus

                       Dim agentStatus As New AgentStatus()
                       agentStatus.State = [Enum].Parse(GetType(States), status.Attribute("state"))

                       Return agentStatus

                   End Function
               End Class

           End Namespace

           Namespace Phone

               Public Class PhoneStatus

                   Private _model As String
                   ''' <summary>
                   ''' Model number of phone
                   ''' </summary>
                   Public Property Model() As String
                       Get
                           Return _model
                       End Get
                       Set(ByVal value As String)
                           _model = value
                       End Set
                   End Property

                   Private _serial As String
                   ''' <summary>
                   ''' Serial number of phone
                   ''' </summary>
                   Public Property Serial() As String
                       Get
                           Return _serial
                       End Get
                       Set(ByVal value As String)
                           _serial = value
                       End Set
                   End Property

                   Private _mac As String
                   ''' <summary>
                   ''' MAC address of phone's NIC adapter
                   ''' </summary>
                   Public Property Mac() As String
                       Get
                           Return _mac
                       End Get
                       Set(ByVal value As String)
                           _mac = value
                       End Set
                   End Property

               End Class

               Public Class PhoneStatusFactory
                   Public Shared Function Parse(ByVal status As System.Xml.Linq.XElement) As PhoneStatus

                       Dim phoneStatus As New PhoneStatus

                       phoneStatus.Model = status.Attribute("model")
                       phoneStatus.Serial = status.Attribute("serial")
                       phoneStatus.Mac = status.Attribute("mac")

                       Return phoneStatus

                   End Function
               End Class

           End Namespace

           Namespace Ringer

               Public Class RingerStatus

                   Dim _tone As String
                   Public Property Tone() As String
                       Get
                           Return _tone
                       End Get
                       Set(ByVal value As String)
                           _tone = value
                       End Set
                   End Property

               End Class

               Public Class RingerStatusFactory
                   Public Shared Function Parse(ByVal status As XElement) As RingerStatus

                       Dim ringerStatus As New RingerStatus()

                       ringerStatus.Tone = status.Attribute("tone")
                       Return ringerStatus

                   End Function
               End Class

           End Namespace

       End Namespace

       Namespace DataSource

           Public Class Status

               Private _agentStatus As Items.Agent.AgentStatus
               Public Property AgentStatus() As Items.Agent.AgentStatus
                   Get
                       Return _agentStatus
                   End Get
                   Set(ByVal value As Items.Agent.AgentStatus)
                       _agentStatus = value
                   End Set
               End Property

               Private _phoneStatus As Items.Phone.PhoneStatus
               Public Property PhoneStatus() As Items.Phone.PhoneStatus
                   Get
                       Return _phoneStatus
                   End Get
                   Set(ByVal value As Items.Phone.PhoneStatus)
                       _phoneStatus = value
                   End Set
               End Property

               Private _ringerStatus As Items.Ringer.RingerStatus
               Public Property RingerStatus() As Items.Ringer.RingerStatus
                   Get
                       Return _ringerStatus
                   End Get
                   Set(ByVal value As Items.Ringer.RingerStatus)
                       _ringerStatus = value
                   End Set
               End Property

           End Class

           Public Class StatusFactory

               ' Values come from devices over the network and recieve as XML.
               Private phoneStatus As System.Xml.Linq.XElement = XElement.Parse("<phone mac=""000000000000"" model=""1977"" serial=""00012345677"" />")
               Private agentStatus As System.Xml.Linq.XElement = XElement.Parse("<agent state=""available"" />")
               Private ringerStatus As System.Xml.Linq.XElement = XElement.Parse("<ringer tone=""New Wave"" />")

               Public Function Parse() As Status

                   Dim s As New Status
                   s.AgentStatus = Items.Agent.AgentStatusFactory.Parse(agentStatus)
                   s.PhoneStatus = Items.Phone.PhoneStatusFactory.Parse(phoneStatus)
                   s.RingerStatus = Items.Ringer.RingerStatusFactory.Parse(ringerStatus)

                   Return s

               End Function

           End Class

       End Namespace

   End Namespace
Concerns/Questions:

1. This utilizes the Factory Method pattern since I have the "Parse" function that returns a new object, right?
2. Since I do not have direct values that do not require additional processing I wanted to remove passing XML to the constructor. I thought this is exactly what a Factory is for. Typically I only use a contruction if I have actual valid property values that do not require extra work?
3. I cannot be for certain, but would this be considered a Abstract Factory? What would be required to make it so? I know I could use an Interface, but wanted to keep the methods as Shared/Static and you cannot have a SharedVirtual signature in an Interface. The reason I wanted them shared is becuase it looks cleaner and do not need to instanciate the Factory objects to return the various status objects. Does this even matter, is there a preference?
4. What other creational patterns would be better suited? Builder?
5. Any other suggestions on the model design?

TIA,

Steve
 



100   96.6
Sep 15, 2010

1. The intent of factory method pattern is to "Define an interface for creating an object, but let subclasses decide which class to instantiate". Whereas when if i see the source code  AgentStatusFactory class defining the "Parse" function and returning the instance of AgentStatus class. After checking the source code i would say this is just a variation of factory method pattern which we can call it as simple factory pattern. If the mentioned structure is changed according to enclosed class diagram, it will turned to be factory Method pattern.

2. Yes the mentioned point is correct.

3.Factory Method Pattern provides an interface for creating an object, but let subclasses decide which class to instantiate. Whereas Abstract Factory Pattern provides an interface for creating families of related or dependent objects without specifying their concrete class. Please refer to following URL.

http://img34.imageshack.us/i/absfactory.png/
http://www.codeproject.com/KB/architecture/FactoryPattern.aspx

4. For the given scenario Factory Method pattern is best. Builder has to be used when the creation process is tedious and has to be reused. In other words Builder design pattern has to be used when the creation of a specific object  has to be done over several steps.

5. I think given the secnario the above code snippets looks good in many ways maintainability/reusability. But if you could provide more information or goal you want to achieve, it would be helpful.