Design Patterns

Basic Java before diving into Design Patterns

What are design patterns?

They are elegant solutions to repeating problems in software design

Design patterns were introduced by Gang Of Four authors hence we call design patterns "GOF Patterns"

The design patterns (DP) are categorized into 3

  • Creational - all about different ways to create objects

  • Structural - all about the relationship between these objects

  • Behavioral - communication between these objects

Benefits of learning DP

  • You can build reusable, maintainable, and extensible software no matter what kind of app you build

  • You can learn new frameworks and libraries sooner when you know DP as all frameworks revolve around them

  • Knowing the design patterns, we can communicate with the other developers at a more abstract level

"Hey we can use command pattern to improve the code"

Before we proceed it's better to have an idea of basic java concepts which is essential to understand as will be learning design patterns in Java, so let's dive into JAVA basics

Java Basics

  • Package - The Package is a container for one or more classes. By convention, we use the reverse domain name

  • Static method - We can call the method directly without having to create an instance of that class. Like the main method

  • Constructor - The method that gets called when we create the instance of that class

  • Coupling - It tells how much one class is dependent on the other class. Let's say we are using a User instance inside the Main class. Adding a parameter to the constructor of the User class breaks the code in the Main class unless we make necessary modifications. Also, if your code has 1000 classes and you change one class by adding a small character and this might not be a breaking change and doesn't affect other codes, but the sad part is all the classes need to be recompiled due to this change thereby reducing the performance. This is tight coupling ( tightly dependent on each other) A Car is an example of a loosely coupled system where we can change just the tire without affecting other parts.

Well, then how do we implement a loosely coupled system 🤔🤔. We can do that using Interfaces

  • Interface - A contract that specifies the capabilities that a class should provide. It defines what all a class should implement by default.

Imaging you want to open a restaurant. You need a chef. It doesnt matter who the chef is and you're not dependent on a particular person who is a chef. You're only dependent on a person who can provide the role of a chef. It can be anyone with the chef's capabilities.

4 Pillars of OOP

1. Encapsulation

Bundling the data and methods that operate on that data within a single unit or a class and hiding the values or state of an object inside a class.

public class Account{
 
  private float balance;
  
  public void setBalance(float balance){
  
     this.balance = balance;
     
  }
  
  public float getBalance(){
  
     return this.balance;
     
  }
}

Here we're encapsulating the account-related capabilities in the Account class and making the balance variable private. We also provide a way to change the balance and get the balance to the other classes using these getters and setters.

2. Abstraction

Reduce complexity by hiding unnecessary details. Let's say the user would like to send a mail. For sending a mail, he should be aware of thesendEmail()alone and nothing else. But for sendEmail()to work, it should depend on connect(), disconnect().

public class SendEmail(){
  
  public void sendEmail(){
    connect();
    authenticate();
    //send email code
    disconnect();  
  }
  
  // below methods can be abstracted/hidden by the user as he need not know about these
  
  private void connect(){
    System.out.println("Connected")
  }
  
  public void disconnect(){
    System.out.println("Connected")
  }
  
}

3. Inheritance

Mechanism to resuse methods across classes.

4. Polymorphism - ( Many Forms )

Poly - Many, Morph - Forms : An object can take many forms

Let's say we have to implement a draw() method. We have a UIControl class where we have two options to draw. We can draw TextBox as well as Circle. Drawing a circle is different from drawing a triangle. Meaning, both the draw methods should implement code differently but the method names should be the same. This is called polymorphism.

public class Main {

    public static void main(String[] args) {
        drawUIControl(new TextBox()); // prints "Drawing text box"
        drawUIControl(new CheckBox()); // prints "Drawing check box"

    }
    // at runtime, UIControl class (paramerter) can take many different forms (TextBox or CheckBox)
    public static void drawUIControl(UIControl uiControl){ 
        uiControl.draw();
    }
}


// we can not instantiate an abstract class, we can only extend it
public abstract class UIControl {

    public void enable(){
        System.out.println("Enabled");
    }

    public abstract void draw();
}

// Type of UIControl
public class TextBox extends UIControl {

   @Override
    public  void draw() {
       System.out.println("Drawing text box");
     }
}

// Type of UIControl
public class CheckBox extends UIControl {

    @Override
    public  void draw() {
        System.out.println("Drawing check box");
    }
}

Done with Java basics. Now will learn the two patterns.

We will learn two patterns Memento pattern and State pattern. It's easy to follow Mosh's video from here and practice a few times https://www.youtube.com/watch?v=NU_1StN5Tkk&ab_channel=ProgrammingwithMosh

Timestamp : Watch from 36.55

Memento pattern

Last updated