← Back to Advanced Java Course | Chapter 6: Design Patterns | Lesson 10 of 14

Java का Command Pattern

Command pattern किसी request को execute method वाले एक standalone object के रूप में encapsulate करता है, किसी action के invoker को उस object से decouple करते हुए जो असल में उसे perform करता है।
Syntax
java
interface Command {
    void execute();
}

class ConcreteCommand implements Command {
    private Receiver receiver;
    public void execute() { receiver.action(); }
}

What is the Command Pattern?

Command pattern किसी request को एक standalone object के रूप में encapsulate करता है, आमतौर पर एक single execute method के साथ, एक action को ऐसी चीज़ में बदलते हुए जिसे store किया जा सके, पास किया जा सके, और invoke किया जा सके बिना caller को इसकी details जानने की ज़रूरत के।

उदाहरण: What is the Command Pattern?

java
public class Main {
	interface Command { void execute(); }
	public static void main(String[] args) {
		Command turnOn = () -> System.out.println("Light turned on"); // a request as a standalone object
		turnOn.execute();
	}
}

Encapsulating a Request

एक command किसी action को invoke करने वाले object (invoker) को उस object से decouple करता है जो असल में इसे perform करता है (receiver), क्योंकि invoker हमेशा सिर्फ उसे दिए गए command पर execute call करता है।

उदाहरण: Encapsulating a Request

java
public class Main {
	static class Light { void on() { System.out.println("Light on"); } }
	interface Command { void execute(); }
	static class LightOnCommand implements Command {
		Light light;
		LightOnCommand(Light light) { this.light = light; }
		public void execute() { light.on(); } // invoker only calls execute
	}
	public static void main(String[] args) {
		Command cmd = new LightOnCommand(new Light());
		cmd.execute();
	}
}

Undo and Redo

execute के साथ एक undo method जोड़ना हर command को अपने खुद के effect को उल्टा करने का तरीका जानने देता है, और executed commands को एक stack में store करना multi-level undo और redo implement करने का एक स्वाभाविक तरीका देता है।

उदाहरण: Undo and Redo

java
import java.util.*;
public class Main {
	interface Command { void execute(); void undo(); }
	public static void main(String[] args) {
		StringBuilder text = new StringBuilder();
		Deque<Command> history = new ArrayDeque<>();
		Command append = new Command() {
			public void execute() { text.append("Hi"); }
			public void undo() { text.setLength(text.length() - 2); }
		};
		append.execute();
		history.push(append);
		history.pop().undo(); // reverses its own effect
		System.out.println("'" + text + "'");
	}
}

Command Queues

चूंकि एक command सिर्फ एक object है, कई commands को एक queue या list में इकट्ठा किया जा सकता है और बाद में, order में, process किया जा सकता है, task scheduling, batching, या requests को चलने से पहले log करने जैसी features को संभव बनाते हुए।

उदाहरण: Command Queues

java
import java.util.*;
public class Main {
	interface Command { void execute(); }
	public static void main(String[] args) {
		Queue<Command> queue = new LinkedList<>();
		queue.add(() -> System.out.println("Task 1"));
		queue.add(() -> System.out.println("Task 2")); // collected, processed later in order
		while (!queue.isEmpty()) queue.poll().execute();
	}
}

Command vs Direct Method Calls

एक direct method call caller को एक specific class और method से कसकर जोड़ देता है, जबकि उसी action को Command object में wrap करना उन्हें decouple कर देता है, invoker को यह जाने बिना कि command असल में क्या करता है उसके साथ काम करने देते हुए।

उदाहरण: Command vs Direct Method Calls

java
public class Main {
	static class Light { void on() { System.out.println("Light on"); } }
	interface Command { void execute(); }
	public static void main(String[] args) {
		Light light = new Light();
		light.on(); // tightly coupled direct call
		Command cmd = light::on; // decoupled -- invoker doesn't know it's a Light
		cmd.execute();
	}
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. execute() चलने पर पिछली state save किए बिना undo() लिखना, जिससे restore करने के लिए कुछ नहीं बचता।
  2. invoker से सिर्फ execute() call करवाने के बजाय receiver को सीधे call करवाना, जो coupling को वापस ले आता है।
  3. कोई नया command execute होने के बाद redo stack को clear न करना, जिससे redo ऐसे actions replay कर सकता है जिनका अब कोई मतलब नहीं रहा।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.