Tuesday, November 5, 2024

Fluent interface pattern

 public class UserConfigurationManager {
    private String userName;
    private String password;
    private UserConfigurationManager() {
    }
    public UserConfigurationManager setUserName(String userName) {
        this.userName = userName;
        return this;
    }
    public UserConfigurationManager setPassword(String password) {
        this.password = password;
        return this;
    }
    public static UserConfigurationManager make(Consumer<UserConfigurationManager> consumer) {
        System.out.println("making configuration..........");
        UserConfigurationManager configurationManager = new UserConfigurationManager();
        consumer.accept(configurationManager);
        return configurationManager;
    }
}

public class MainApp {
    public static void main(String[] args) {
        UserConfigurationManager.make(configManager -> configManager.setUserName("lokman").setPassword("12345"));
    }

Note: Fluent pattern can be used to define Model in JPA

Monday, October 21, 2024

Command Design Pattern using lambda expression

 Command design pattern: The main concept of command pattern is how the command will be executed that process is encapsulated in a class . So the the process will be hide into that class.

Command :  Command object knows about receiver and call a method of receiver.

Receiver:  Who receives command and acts based on that command;

Invoker: Who only have reference of command interface . Who does not know about the implementation of the command . 

Client: It hold all the list of command. Just invoke to the invoker whatever need .

Example:

Command:

public interface Command {
    void execute();
}

public class OnCommand implements Command {
    private Tv tv;
    public OnCommand(Tv tv) {
        this.tv = tv;
    }
    @Override
    public void execute() {
        tv.switchOn();
    }
}

 public class OffCommand implements Command {
    private Tv tv;
    public OffCommand(Tv tv) {
        this.tv = tv;
    }
    @Override
    public void execute() {
        tv.switchOff();
    }
}

Invoker:

public class RemoteControl {
    private List<Command> history = new ArrayList<>();
    public void press(Command command) {
        history.add(command);
        command.execute();
    }
}

Client:

public class TvClient {
    public static void main(String[] args) {
        Tv tv = new Tv();

        Command onCommand = new OnCommand(tv);

        Command offCommand = new OffCommand(tv);
        RemoteControl remote = new RemoteControl();
        remote.press(onCommand);
        remote.press(offCommand);
    }
}

Here command interface has  one abstract method. So we can use lambda expression here . so no need to create OnCommand and OffCommand class .

public class TvClient {
    public static void main(String[] args) {
        Tv tv = new Tv();
        RemoteControl remote = new RemoteControl();
        remote.press(tv - > switchOn);
        remote.press(tv -> switchOff);

    }

we can replace it using method reference also ,

public class TvClient {
    public static void main(String[] args) {
        Tv tv = new Tv();
        RemoteControl remote = new RemoteControl();
        remote.press(tv:: switchOn);
        remote.press(tv:: switchOff);

    }
}

Sunday, October 6, 2024

What is lamda expression and how it solve real world problem?

 A lambda expression is the representation of anonymous function(function that doesn't have any function name)lambda expression is key feature of functional programming. Functional programming is followed by declarative programming approach . 

Declarative programming: Declarative programming is a programming approach where main focus is on what is need but not how to do .

Now lets have an example where we want to filter Contact information based on certain criteria .

Model:

@Getter

@Setter

@ToString

public class Contact {
    public enum Gender {
        MALE, FEMALE
    };
    private String name;
    private String email;
    private int age;
    private Gender gender;
    public Contact(String name, String email, int age, Gender gender) {
        this.name = name;
        this.email = email;
        this.age = age;
        this.gender = gender;
    }
}

Now we want to filter those contact whose age is greater than 18 and less than 25 and gender MALE. 

So what can we do ?

Ans: We can create a ContactFilterService class that will filter and return filtered contacts.

public class ContactFilterService {
public List<Contact> findContactsAgeBetween18to25AndMale(List<Contact> contacts) {
List<Contact> filteredContacts = new ArrayList<>();
for (Contact contact : contacts) {
      if (18 <= contact.getAge() && contact.getAge() <= 25
       && contact.getGender() == Gender.MALE) {
        filteredContacts.add(contact);
        }
    }
    return filteredContacts;
    }

Now I want to filter contacts where age is age is greater than 18 and less than 25 and gender FEMALE.

So we can can create another method to do that . 

But ContactFilterService growing , because in every need we are creating new methods and we are duplicating code.

We can create a generic method in ContactFilterService class that only check the condition .

We don't want to modify this class every time . We want to pass the filter logic from outside of the class .

lets do that,

Interface:

 public interface FilterCriteria {
    boolean match(Contact contact);

}

ContactFilterService:

public class ContactFilterService {

    public List<Contact> filter(List<Contact> contacts, FilterCriteria criteria) {
        List<Contact> filteredContacts = new ArrayList<>();
        for (Contact contact : contacts) {
            if (criteria.match(contact)) {
                filteredContacts.add(contact);
            }
        }
        return filteredContacts;
    }

} 

MainApp:

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

     Contact contact1 = new Contact("rupta", "rupta@gmail.com", 25, Contact.Gender.FEMALE);
        Contact contact2 = new Contact("asik", "asik@gmail.com", 30, Contact.Gender.MALE);
        Contact contact3 = new Contact("ruhul", "ruhul@gmail.com", 22, Contact.Gender.MALE);
        Contact contact4 = new Contact("nusrat", "nusrat@gmail.com", 31,                                           Contact.Gender.FEMALE);
        List<Contact> contacts = Arrays.asList(contact1, contact2, contact3, contact4);
        ContactFilterService contactFilterService = new ContactFilterService();

         List<Contact> filterdList = contactFilterService.filter(contacts, new FilterCriteria() {
            @Override
            public boolean match(Contact contact) {    
                if(18 <= contact.getAge() && contact.getAge() <= 25) {
                    return true;
                }
                return false;
            }
        });
        System.out.println(filterdList);
    }

    }

}

 Here we are just passing our logic into ContactFilterService filter() method.

So we no need to create new method every time .

 Now we have solved one problem but we still implementing anonymous inner class as boilerplate code.

every time we are writing new FilterCriteria() and @Override and return type of the function.

So here we can pass lambda expression. 

lets refactor our code,

 List<Contact> filterdList = contactFilterService.filter(contacts, (Contact contact) -> {
            return 18 <= contact.getAge() && contact.getAge() <= 25;
        });
        System.out.println(filterdList);

Here lamda expression,

(Contact contact) -> {
            return 18 <= contact.getAge() && contact.getAge() <= 25;
        }

But think in mind ,

Lambda expression will apply in Functional Interface only . 

A functional interface only have one abstract method.

The type of lambda expression is functional interface(interface that has at least an abstract method).

The target type of the lambda expression is functional interface .



 


Friday, August 30, 2024

High level overview of rabbitMQ

Messaging in software industry is the process of sending message between applications or services in a loose couple manner . The application can be written in different languages or can be in different platform does not matter .

RabbitMQ implements AMQP(Advanced Message Queuing protocol). 

One of the major benefit of using RabbitMQ is that , a TCP connection can accomodate multiple channel . So no need to open multiple TCP connection and close them to RabbitMQ broker.


Tuesday, July 9, 2024

Implement queue using Double ended Linked List

 To implement a queue using Linkedlist we can use double ended Linkedlist.

A double ended Linkedlist has first and last node pointer. So we can insert item at last to implement enqueue operation  using last pointer. To implement dequeue operation we can remove item from the first using first node.

Below is the implementation:

class Link:

public class Link {
    public long data;
    public Link next;
    public Link(long data) {
        this.data = data;
    }
    public void displayLink() {
        System.out.println("data :"+ data);
    }
}

class FirstLastList:

public class FirstLastList {
    private Link first;
    private Link last;
    public FirstLastList() {
        first = null;
        last = null;
    }
    public boolean isEmpty() {
        return first == null;
    }
    public void insertLast(long data) {
        Link newLink = new Link(data);
        if (isEmpty()) {
            first = newLink;
        } else {
            last.next = newLink;
        }
        last = newLink;
    }
    public long removeFirst() {  
        Link temp = first;
        first = first.next;
        return temp.data;
    }
    public void display() {
        Link current = first;
        while (current != null) {
            System.out.print(current.data + "-->");
            current = current.next;
        }
    }
}

class LinkQueue:

public class LinkQueue {
    private FirstLastList firstLastList;
    public LinkQueue() {
        this.firstLastList = new FirstLastList();
    }
    public void enqueue(long data) {
        firstLastList.insertLast(data);
    }
    public void dequeue() {
        firstLastList.removeFirst();
    }
    public void displayQueue() {  
        firstLastList.display();
    }
}

class MainApp:
public class MainApp {
    public static void main(String[] args) {
        LinkQueue queue = new LinkQueue();
        queue.displayQueue();
        System.out.println("after enqueue new item");
        queue.enqueue(10);
        queue.enqueue(20);
        queue.enqueue(30);
        queue.enqueue(40);
        queue.enqueue(50);
       
        queue.displayQueue();
        System.out.println("\n");
       
        queue.dequeue();
        System.out.println("after dequeue item");
        queue.displayQueue();
    }
}

Monday, July 8, 2024

Implemented Stack using LinkedList

Link class: 

public class Link {
    public long data;
    public Link next;
    public Link(long data) {
        this.data = data;
    }
    public void displayLink() {
        System.out.println("data :"+ data);
    }
}

 LinkedList class:

public class LinkedList {
    private Link first;
    public LinkedList() {
        first = null;
    }
    public boolean isEmpty() {
        return first == null;
    }
    public void insertFirst(long data) {
        Link newLink = new Link(data);
        newLink.next = first;
        first = newLink;
    }
    public long deleteFirst() {
        Link temp = first;
        first = first.next;
        return temp.data;
    }
    public void displayList() {
        Link current = first;
        while (current != null) {
            System.out.println(current.data + "----");
            current = current.next;
        }
    }
}

 LinkStack class:
public class LinkStack {
    private LinkedList theList;
    public LinkStack() {
        theList = new LinkedList();
    }
    public void push(long data) {
        theList.insertFirst(data);
    }
    public void pop() {
        theList.deleteFirst();
    }
    public boolean isEmpty() {
        return theList.isEmpty();
    }
    public void displayList() {
        System.out.println("displaying the stack---------------");
        theList.displayList();
    }
}

MainApp:

 public class MainApp {
    public static void main(String[] args) {
        LinkStack stack = new LinkStack();
        stack.push(10);
        stack.push(20);
        stack.push(30);
        stack.push(40);
        stack.push(50);
        stack.displayList();
        stack.pop();
        stack.displayList();
    }
}

Fluent interface pattern

 public class UserConfigurationManager {     private String userName;     private String password;     private UserConfigurationManager() { ...