Q:

Explanation of Java Factory Design Pattern or Factory Class

I am going through HackerRank and had a quick question regarding the Factory Design Pattern or Factory Class. I am going through a basic challenge (https://www.hackerrank.com/challenges/java-factory/problem) and was able to solve it (code shown below). I wrote the portion of the code that is indicated by the comments below, while the rest was provided. 
import java.util.*;
import java.security.*;
interface Food {
     public String getType();
    }
    class Pizza implements Food {
     public String getType() {
     return "Someone ordered a Fast Food!";
     }
    }
//I implemented the part starting here    
        class Cake implements Food {

         public String getType() {
         return "Someone ordered a Dessert!";
         }
        }

    class FoodFactory {
        public Food getFood(String order) {

if (order.equalsIgnoreCase("Pizza")){
        return new Pizza();}

else return new Cake();

}//End of getFood method; this is the end of the part I implemented

    }//End of factory class

    public class Solution {

     public static void main(String args[]){
            Do_Not_Terminate.forbidExit();

        try{

            Scanner sc=new Scanner(System.in);
            //creating the factory
            FoodFactory foodFactory = new FoodFactory();

            //factory instantiates an object
            Food food = foodFactory.getFood(sc.nextLine());

            System.out.println("The factory returned "+food.getClass());
            System.out.println(food.getType());
        }
        catch (Do_Not_Terminate.ExitTrappedException e) {
            System.out.println("Unsuccessful Termination!!");
        }
     }
    }

I have spent quite a bit of time reading through several examples online of the Factory Design Pattern, but it isn't exactly clear to me what is the purpose of the Factory Pattern and why it is beneficial or what it is simplifying/what problem it is solving. Similarly, trying this actual example hasn't quite elucidated the issue to me. 
Can someone explain this in a very basic way and similarly, what would be alternatives to using the Factory Pattern? Perhaps this code that was provided in this exercise oversimplified the issue and this is why I am not clear on what the Factory accomplished. Thank you for some help as some real world color would help greatly. I have read about various design patterns and know what they are but I don't understand the issue well enough having limited real world experience with them

A:

The basic idea of a factory is 2 things:

Obfuscate to the user (the developer) how objects are created
Put all object creation through a single place of origin.

Why do you need the factory in the first place?
Well the easiest answer is so that you could control the object creation.
Let's take a real world example:
You want to write an analytics for your app. 
You happily write a class that implements some library for analytics that you use.
And go over all of your app and write AnalyticsEventManager().sendEvent(blabla)
What is the problem with this?

There came a day you want to add another analytic or replace the
current one   
How do you check that all the places you need the analytic it is actually invoked?

Well factory to the rescue.
instead of AnalyticsEventManager().sendEvent(blabla)
You write an interface that has a "sendEvent" method
interface AnalyticEventSender {
   void sendEvent(String eventData); 
}

Then you have a few instances of different classes that implement this analytic
class FacebookAnalytic implements AnalyticEventSender {
    @Override
    public void sendEvent(String eventData){
       System.out.println("I am facebook analytics sender:" + eventData);
    }
}

Then you have 
class TestAnalytic implements AnalyticEventSender {
    @Override
    public void sendEvent(String eventData){
       System.out.println("I am test analytics sender:"+eventData);
    }

}

Then you have analytic factory 
class AnalyticFactory {
   public static AnalyticEventSender create(){
        if(allowFacebookAnalytic){
            return new FacebookAnalytic();
        }else {
            return new TestAnalytic();
        }
   }
}

and so just like that you were able to replace ALL the instances of your analytic based on some boolean (the reason for changing the analytic is up to the discretion of the one who wrote the code)
And now instead of doing AnalyticEventManager().sendEvent you would write AnalyticFactory.create().sendEvent(blabla)
So now, If you want to check that your events are actually printed the way you want them to be printed, you just replace the instance that is returned in the factory with the TestAnalytic and check that the events are printed, without actually going through the real facebook module.
This is true for many other applications, not just analytics.

