In the previous article, we discussed about the Singleton design pattern and its sample usage. In this article, we will discuss one more, Object Factory Design Pattern in Golang. Object Factory is the most probably most used design pattern in the OOP world. It deals with instantiation and creation of objects and hence is a part of the creational design pattern. This design pattern was introduced to us in the famous book Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides.

In Factory Pattern, we can create the object without exposing the logic of the client that is creating the object. It is like the end-user asks for a certain kind of object and it is given to him, abstracting all the explanation as to how the object was obtained, etc. Let us take an example to help us understand it better. Let us suppose there is a school which has three streams: Science, Arts, and Commerce. One fine day the manager of the school comes and wishes to talk to a student each of a Science stream. He is unaware of the exact location of the classes of the Science streams. He just orders the headmaster “Bring me, science student”.
It is now the headmaster who goes to the actual class and calls a student to meet the manager. Please note the manager is opaque to all the details of how a science student is called.
This in some ways is the use-case of the object factory pattern. The student is the object and the headmaster is the object factory. The user (manager) just tells the object factory (headmaster) which kind of object (student) it needs, and the object factory (headmaster) returns the same kind of object (student).

Let us now look at how will it look like in coding terms.

func main() {
  student, err := factory.GetStudent("Science")
  student.Talk()
}

The factory is the headmaster. The manager asks the manager to get a student and just gives the information that the stream is Science. Factory (headmaster) hiding all the implementation details from the manager, instantiates the object of a given type (calls the student of Science stream) and returns.

 

Golang does not have the concept of classes and object, but it has struct{} and interfaces which more than make up for it.

Let us now look step by step, how to use this example and implement the object Factory Design Pattern in Golang.

  • This is the parent entity (the parent object which will be instantiated throughout). This entity will have some behaviors relating to it. This can be achieved in Golang using interfaces. Create an interface student and define some functions (behaviors) to it.
    type Student interface {
      Call()
    } 
    
    
  • Create a Science Student, which is an entity that implements the type Student. We will just make a struct and implement all the functions of the Student interface.
    package factory
    type ScienceStudent struct{}
    
    func (s *ScienceStudent) Call () {
       fmt.Println("This is a science student")
    }
    
    
  • On similar grounds make ArtStudent and CommerceStudent.
    package factory
    type ArtStudent struct{}
    
    func (s *ArtStudent) Call () {
       fmt.Println("This is an arts student")
    }
    
    
    type CommerceStudent struct{} 
    
    func (s *CommerceStudent) Call () {
     fmt.Println("This is a commerce student") 
    }
  • Now we have defined the main entity (student) and it’s different implementations. It is time to define a factory that takes in the requirement from the user and returns the right implementation of the entity.
    func GetStudent( subject string ) Student {
       switch subject {
         case "Science":
                return &ScienceStudent{}
         case "Commerce" :
                return &CommerceStudent{}
         case "Arts":
                return &ArtStudent{}
         default :
                fmt.Println("Invalid Subject given")
                return nil
          }
    }
    
    
  • Let us make a client to drive the code.
            package main
    
            func main() {
    	    student := factory.GetStudent("Science")
    	    student.Call()
            }

And we with these steps. the client is not concerned with the implementation of the internal functioning of fetching an instance of a certain type. He just calls a method telling the type of entity he needs. This is the beauty of the object factory pattern.  We will continue exploring more patterns in the later posts of this series. In the meanwhile, refractor your projects and look where you can apply this pattern.


0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *