Flyweight pattern is categorised as structural pattern,Which is used to reduce number of object creations by using existing similar objects which in turn helps in reducing the memory foot print and increasing the performance of an application. lets take some real world example where you need to print employee details whose salary and name varies, instead of creating new ones, so as the name the memory used by the code will be weight of a fly during run time(flight time of the code) and now lets dive into implementation first.

1) Interface

public interface Employee {
    String getDetails();
}

I have create basic interface to get the required details of the employee,so this would be helpful when we are working in peer development environment. you can skip this if it is not necessary for you.

2) Implementation

public class EmployeeImpl implements Employee {
    private String name;
    private String occupation;
    private String age;
    private String salary;
    private String gender="";


    public EmployeeImpl(String gender) {
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

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

    public String getOccupation() {
        return occupation;
    }

    public void setOccupation(String occupation) {
        this.occupation = occupation;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getSalary() {
        return salary;
    }

    public void setSalary(String salary) {
        this.salary = salary;
    }

    @Override
    public String getDetails() {
        return name + ":" + occupation + ":"+age+":"+salary;
    }
}

This is a basic Java POJO class which contains some fields which we needs to manipulate.the code is self explanatory.

3) Factory

public class EmployeeFactory {
    private static final HashMap<String, Employee> employees = new HashMap<>();

    public static Employee getEmployee(String gender) {
        if(employees.containsKey(gender.toLowerCase())){
            return employees.get(gender.toLowerCase());
        }
        switch (gender.toLowerCase()) {
            case "male":
                EmployeeImpl male = new EmployeeImpl(gender.toLowerCase());
                employees.put(gender.toLowerCase(),male);
                break;
            case "female":
                EmployeeImpl female = new EmployeeImpl(gender.toLowerCase());
                employees.put(gender.toLowerCase(),female);
                break;
             default: throw new RuntimeException("Invalid person type");
        }
        return employees.get(gender.toLowerCase());
    }
}

This is just like traditional factory pattern which return the instance of the object based on switch condition. so in this example i have differentiated the creation class based on gender, likewise you can create by age or some common factor according to your needs, based on input as gender my method `public static Employee getEmployee(String gender)` creates two instance of EmployeeImpl and stores it into an HashMap for first time and return same object every time when accessed.

3) Demo

import java.util.stream.IntStream;

public class FWDemo {
    public static void main(String[] args) {

        IntStream stream = IntStream.range(1, 10);
        stream.forEach(s-> {
            EmployeeImpl emp = (EmployeeImpl) EmployeeFactory.getEmployee(s%2== 0 ? "male":"female");
            emp.setName("name"+s);
            emp.setAge(s*10+"");
            emp.setOccupation("occupation"+s);
            emp.setSalary(s*1000 +"$");
            emp.setName("name"+s);
            System.out.println("==================================");
            System.out.println("\n");
            System.out.println(emp.getDetails());
            System.out.println(emp.hashCode());
            System.out.println("\n");
            System.out.println("==================================");
        });

    }
}

so lets run the code. and print employee details and below i have pasted the o/p below

==================================


name1:occupation1:10:1000$
1873653341


==================================
==================================


name2:occupation2:20:2000$
25126016


==================================
==================================


name3:occupation3:30:3000$
1873653341


==================================
==================================


name4:occupation4:40:4000$
25126016

So we if you observer the hash code of the o/p we have only two instance i.e `1873653341` and `25126016` for 10 iterations.so we have only created only two instance, what if we have 1k, thus flyweight pattern uses very little memory foot print.

5) Real world Use Case

  • While printing large no text on Screen.
  • Can be used in Kafka consumer or producer to reduce the load on GC.
  • Can be used in ETL module.
  • While generating the chunked o/p.