The Hollywood Principle

The Hollywood Principle


Hollywood.jpg



Hollywood Principle says:  "Don't call us, we'll call you"

This little sentence opens up a new viewpoint in Software industries. This is one of the important principles every developer should know.

In this article, we will try to discuss this principle.

"Don't call us, we'll call you" what does it mean?

In layman terms,  you don’t have to bother about when your turns come, when your turns come they will call you.

But What you and they denote here?

To explain "you" and "they" in technical terms first we need to understand How a Software design works.

When we design a software we try to implements two things.

  1. API
  2. Framework.


  1. API:  API used to publish some methods/functions so the caller/user of the API call this method to get some useful information. So caller does not have any action points to take only call methods and get output.
  2. Framework: The Framework is a little bit critical than API. The framework is maintaining an algorithm but it expects the value to be produced by the caller of the Framework. To put it simple way, Framework takes Strategy or Business implementation from the caller and call it when it requires.



By Hollywood principle, we can make Framework works, where you means the Strategy or business implementation, which needs to be fed, and they denote framework engine/implementation which calls fed strategy when required.

Real time Example:

Spring DI: Think about Spring where we declare beans in XML, and Spring container call these beans create Spring beans, inject other beans into it and returns fully configured bean.  So by the help of XML, we feed the strategy and Spring container calls them when required. We often called it Dependency Injection so Hollywood Principle’s another name is IOC(Inversion of Control).

Struts 1.x: Pay attention to Struts 1.x implementation where caller of Struts extends ActionClass and provide  Business implementations in the Action class and Struts framework call those Action class based on the URL mentioned in Struts config file. So here Action class is Strategy and Struts framework invokes it.

Observer pattern/Listener in Swing:  Think about Swing’s actionListener we subscribe to an event like button click, on Blur etc and when this event occurs Swing call our code written in the actionPerformed method.


Apart from this Servlet / EJB all maintains lifecycles so underlying server calls appropriate life cycle method when the servlet or EJB state changed like init, service, destroy or ejbActivate ejbPassivate etc.

We call those methods as Callback methods because Framework call this method we don’t have to call them but we may provide the implementations of those methods if we want to push some strategies in Framework.



Let see a use case where we can use Hollywood principle

Say Cognizant has a Resume upload portal where job seeker uploads their resumes. When there is an On campusing happens in Cognizant they will call them by sending a mail to their inbox.

We can implement the same by Hollywood principle,
Jobseeker uploads their resumes in Job portal and Cognizant send mail to them when an on campusing occurs.
cognizant says : Don’t call me I will call you. :)Hollywood (2).jpg

Let see the implementation.

Assumption : Here I have not introduced any interface for sake of simplicity and not add any complex scenario like a priority, reset, GroupWise mail sending etc. as I just wanted to show How Hollywood principle works.


Resume.java

/**
*
*/
package com.example.hollywood;

/**
* @author Shamik Mitra
*
*/
public class Resume {
    private String email;
    private String name;
    private String content;
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    @Override
    public String toString() {
        return "Resume [email=" + email + ", name=" + name + ", content=" + content + "]";
    }
   
   

}


CognizantJobPortal.java

/**
*
*/
package com.example.hollywood;

import java.util.ArrayList;
import java.util.List;

/**
* @author Shamik Mitra
*
*/
public class CognizantJobPortal {
   
    private static CognizantJobPortal portal = new CognizantJobPortal();
   
    public static CognizantJobPortal get(){
        return portal;
    }
   
    private CognizantJobPortal(){
       
    }
   
   
    private List<Resume> resumeList = new ArrayList<Resume>();
   
    public void uploadContent(String mail ,String name,String content)
    {
        Resume resume = new Resume();
        resume.setName(name);
        resume.setEmail(mail);
        resume.setContent(content);
        resumeList.add(resume);
    }

   
    public void triggercampusing(){
        for(Resume resume : resumeList){
            System.out.println("Sending mail to " + resume.getName() + " at " + resume.getEmail());
        }
    }
}


Test

/**
*
*/
package com.example.hollywood;

/**
* @author Shamik Mitra
*
*/
public class HollywoodTest {
   
    public static void main(String[] args) {
       
        CognizantJobPortal.get().uploadContent("shamik@xyz.com", "Shamik Mitra", "A java developer");
        CognizantJobPortal.get().uploadContent("Ajanta@vvv.com", "Ajanta Mitra", "A PHP developer");
        CognizantJobPortal.get().uploadContent("Swastika@vvv.com", "Swastika Mitra", "A Microservice developer");
        CognizantJobPortal.get().uploadContent("Mayukh@vvv.com", "Mayukh Mitra", "A Network engineer");
        CognizantJobPortal.get().uploadContent("Samir@123.com", "Samir Mitra", "A java Architect");   
        // Now trigger campusing
        CognizantJobPortal.get().triggercampusing();
    }

}

Output:

Sending mail to Shamik Mitra at shamik@xyz.com
Sending mail to Ajanta Mitra at Ajanta@vvv.com
Sending mail to Swastika Mitra at Swastika@vvv.com
Sending mail to Mayukh Mitra at Mayukh@vvv.com
Sending mail to Samir Mitra at Samir@123.com


Please note that in CognizantJobPortal class I maintain a list where uploaded resumes are added. When cognizant triggers a campusing, job portal/framework send the mail to all jobseekers who uploaded the CV to Cognizant.


































Why should I write Getter/Setter?

Why should I write Getter/Setter?

When I started my career in Java, I was confused about getter and setter. One question always comes to my mind why should I write getter/setter? It looks weird kind of syntax to me.

I learned that by public access modifier one field of a class is accessible to any packages, and by Getter/setter what I am doing is same, make the field private and public the getter/setter method, so it can be accessed by any packages.

So, What is the difference between following two expressions?


public String name=”Shamik”;

Caller
========

String name = X.name;   //(X is a object instance);
X.name=”Shamik Mitra”;
private String name=”Shamik”;

public String getName(){
return name;}

public void setName(String name){
this.name=name;}

Caller
=====
String name = X.getname();
X.setName(“Shamik Mitra”);


confused.jpg
What the heck is getter/setter?




Slowly I realize why we use getter/setter & why it is important.

In this Article, I share that realization.

Realization :

The main difference of making a field public VS expose it through getter/setter is to hold the control to the property.If you make a field  public that means you provide direct access to the caller, caller can do anything with your filed knowingly/unknowingly say, caller can send a null value and if you use that filed in another method it may blow up that method by null pointer exception,

But If you provide getter/setter, you provide them an indirect access while taking full control, because the only way to set a value through setter and get a value through getter, So now you have exact one entry and one exit point of your field and getter/setters are methods!!! (Which allows block of codes) so you can do validation check on them and takes the decision you should set the caller value or not, same in getter method you can take decision should you return the actual reference or clone it and return the same to the caller.


So, getter/Setter are work as fuse or circuit breaker where the current has to be passed through fuse if anything goes abnormal fuse detached from the main circuit, so the circuit is safe. The concept is same here if anything goes wrong setter will not pass the value to class member field.

After reading the explanation, I know still you have one question

I understand all but generally, we do not write anything in getter/setter just return the field and set the field, which is same as exposing a field as public so why are you saying all of this?

To answer this question I say writing getter/setter we create a provision to add any validation method in future, currently, there is no validation but if anything goes wrong in future we just add validation logic in the setter.

But still, it creates a debate who are big follower of YAGNI(You aren't gonna need it),
they can say when there are no such validation constraints for a field why should I write getter/setter, I only expose it as public.

As per my understanding, The crux of YAGNI is to Unnecessary not make your code complex, As someone like to think big and try to make their code base so generic that it welcome any changes but most of the changes he/she thinks will never come.

Conclusion: The  getter/setter does not make your code complex and welcome future validations. So Please go for it blindly.




5 Curious cases of Overloading & Generics

5 Curious cases of Overloading & Generics


If you are preparing for an Interview you can expect questions on  generics in java interview for sure , whether it is an position for Team lead or experience developer or Junior. But Generics gets more complicated when it mix with overloading in java. Let see the different scenarios when Generic mix with overloading.

What is generics in Java ?

Generics is technique which facilitates to declare a generic type(T, Irrespective of any Datatype in Java) in methods or class, which will be resolved later when caller of the method or class provide the actual Data Type(Integer, Boolean, String or ant Custom class) and ensure compile time safety but at the run-time it removes the type safety, we call this process as Type erasure.

Benefits of Generics:

By generics, we can achieve some level of the generic type declaration. To be specific Java is a static type language which means when we declare properties or methods we have to provide the type of the parameter or return type at the time of declaration.

But by generics we can defer the process we can declare methods or properties using generic syntax and later on caller can decide what data type pass to it, but remember it is not same as dynamic type language like javascript where var declaration means it represents any data types, on other hand Generics introduce the Type Inference from a bounded context, from Java perspective which is the first step towards functional programming(lambda) adaptation.

Challenges :

The most tricky part of generics is  by Type erasure, java removes the bounded type at runtime, so in java runtime generics and non-generics method/property declaration both are same no difference at all, to maintain backward compatibility  but generics ensure compile time safety so if you declare generics with certain type it only bounds to that certain type if you want to pass any other type compiler will complain instantly.

But as run time its type vanishes so in the case of Overloading we have to think what the method looks after type erasure erases the generic type, to do a perfect overloading unless compiler will complain.

In this Article, we will see 5 such scenarios which can occur often if I miss any please write in the comment section so I can add them to the Article.


Hope you are familiar with the generic syntax and how to use it.




Scenario 1 :

public Integer add(Integer a, Integer b) {
        System.out.println(a+b);
        return a+b;
    }

    /* (non-Javadoc)
    * @see com.example.generics.ICalculate#add(java.lang.Object, java.lang.Object)
    */

    public <T> T add(T a, T b) {
       
        Integer a1 = (Integer)a;
        Integer b1 = (Integer)b;
        Integer resut = a1+b1;
        System.out.println(" Result is" + resut);
        return (T) resut;
       
       
    }


See the two versions of add method can you tell me is it a valid overloading?

Yes this is a valid over loading as after type erasing public <T> T add(T a, T b) this method signature converts to , public Object  add(Object a, Object b) clearly it is different than
public Integer add(Integer a, Integer b) .



Scenario 2:

Now see the following version of overloading


public <T> T add(T a, T b) {
       
        Integer a1 = (Integer)a;
        Integer b1 = (Integer)b;
        Integer resut = a1+b1;
        System.out.println(" Result is" + resut);
        return (T) resut;
       
       
    }
   
   
   
public  Object add(Object a,Object b) {
       
        Integer a1 = (Integer)a;
        Integer b1 = (Integer)b;
        Integer resut = a1+b1;
        System.out.println(" Result is" + resut);
        return  resut;
       
       
    }



Can you tell me is it a valid overloading?

Probably you guess the answer it is not as I told you in previous example public <T> T add(T a, T b) this method signature converts to , public Object  add(Object a, Object b) after type erasing so now both signatures looks same so compiler will complain.


Scenario 3:

Now take the following version

public <T> T add(T a, T b) {
       
        Integer a1 = (Integer)a;
        Integer b1 = (Integer)b;
        Integer resut = a1+b1;
        System.out.println(" Result is" + resut);
        return (T) resut;
       
       
    }

public <T extends Number> T add(T a, T b) {
       
        Integer a1 = (Integer)a;
        Integer b1 = (Integer)b;
        Integer resut = a1+b1;
        System.out.println(" Result is" + resut);
        return (T) resut;
       
       
    }


Is the above a valid Overloading?

Yes it is a valid overloading as after type erasing  public <T> T add(T a, T b)  changed to public Object add(Object a,Object b) but public <T extends Number> T add(T a, T b)  changed to
public Number add(Number a, Number b) as T extends Number means any type which extends Number so after Type erasing it will take Number as infer type.


Exercise :

Can you tell me Is it valid overloading with explanation -- without paste that code in editor?
public Integer add(Integer a, Integer b) {
        System.out.println(a+b);
        return a+b;
    }


public <T extends Number> T add(T a, T b) {
       
    System.out.println(a.getClass().getName());
        Integer a1 = (Integer)a;
        Integer b1 = (Integer)b;
        Integer resut = a1+b1;
        System.out.println(" Result is" + resut);
        return (T) resut;
       
       
    }



Now let take a slightly different example where I try to pass a data type to a collection which will be the bounded context for that collection.

Scenario 4:

public void add(List<Integer> list) {
   
    System.out.println("add list of Integers");
   
   
}

public void add(List<?> list) {
   
    System.out.println("add/concat  list of any type");
   
   
}


Is it a valid overloading?

The Answer is, unfortunately, no, because after type erasing generics will lose its type and would become same as our old list.

So both signatures public void add(List<Integer> list)  and public void add(List<?> list) change to  public void add(List list)  and public void add(List list) so compiler will complain for sure.


Scenario 5 :


public void add(List<Integer> list) {
   
    System.out.println("add list of Integers");
   
   
}

public void add(List<Double> list) {
   
    System.out.println("add list of Integers");
   
   
}


As previous reason it is also not a perfect overloading.

So always pay attention of your generics signature while extending a class or overload method.