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:
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
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?
Net Wreck, Sep 14, 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.
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.
Saurabh Saxena, Sep 15, 2010