Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java command pattern example with Runnable class : Is Receiver missing?

From Examples of GoF Design Patterns in Java's core libraries question, it was quoted that

All implementations of java.lang.Runnable are examples of Command pattern.

As per my understanding of Command pattern,

Client calls Invoker => Invoker calls ConcreteCommand => ConcreteCommand calls Receiver method, which implements abstract Command method.

Have a look at this working example

Command pattern UML diagram from this article is shown as below.

enter image description here

Have a look at this code:

public class ThreadCommand{
    public static void main(String args[]){
        Thread t = new Thread(new MyRunnable());
        t.start();
    }
}
class MyRunnable implements Runnable{
    public void run(){
        System.out.println("Running:"+Thread.currentThread().getName());
    }
}
  1. ThreadCommand is Client
  2. Runnable interface is Command
  3. MyRunnable is ConcreteCommmand
  4. Thread is Invoker with start() method calling ConcreteCommand implementaiton ( which calls run() method)

Is Receiver missing here? Or Does MyRunnable play combined role of ConcreteCommand and Receiver?

like image 411
Ravindra babu Avatar asked Feb 24 '16 18:02

Ravindra babu


2 Answers

A Receiver is optional, depending on whether the ConcreteCommmand owns the business logic to be executed. From page 238 of the book,

A command can have a wide range of abilities. At one extreme it merely defines a binding between a receiver and the actions that carry out the request. At the other extreme it implements everything itself without delegating to a receiver at all.

In the original question we see an example with no receiver, because MyRunnable owns the logic to be executed. In two other answers here we see examples delegating to explicit receivers named Receiver and Account.

like image 175
jaco0646 Avatar answered Sep 25 '22 09:09

jaco0646


One answer has been posted here and it was removed by author immediately. While reading the answer, I have found solution.

I can simply convert above example to Command pattern UML diagram with one small change.

I can pass Receiver object to MyRunnable ( ConcreteCommand ).

Now I have changed my code as below.

public class ThreadCommand{
    public static void main(String args[]){
        Receiver r = new AC();
        Thread t = new Thread(new MyRunnable(r));
        t.start();
    }
}
class MyRunnable implements Runnable{
    private Receiver receiver;
    public MyRunnable(Receiver r){
        this.receiver = r;
    }
    public void run(){
        receiver.execute();
    }
}
interface Receiver{
    public void execute();
}
class AC implements Receiver{
    public void execute(){
        System.out.println("I am AC");
    }
}
class Fan implements Receiver{
    public void execute(){
        System.out.println("I am Fan");
    }
}

Output:

 java ThreadCommand
 I am AC
like image 32
Ravindra babu Avatar answered Sep 26 '22 09:09

Ravindra babu