Autumn SALE
Polecenie

Polecenie w języku Java

Polecenie to behawioralny wzorzec projektowy według którego żądania lub proste działania są konwertowane na obiekty.

Wyżej wymieniona konwersja pozwala odkładać zadania w czasie, uruchamiać je zdalnie, przechowywać ich historię, itp.

Złożoność:

Popularność:

Przykłady użycia: Wzorzec Polecenie jest dość powszechny w kodzie napisanym w Javie jako alternatywa dla wywołania zwrotnego (ang. callback) zakładającego przypisanie akcji elementom interfejsu użytkownika w odpowiedzi na różne interakcje z tymi elementami. Jest stosowany także w celu kolejkowania zadań, śledzenia historii wykonanych działań, itp.

Oto parę przykładów użycia wzorca Polecenie w głównych bibliotekach Java:

Identyfikacja: Jeśli widzisz zestaw powiązanych klas odpowiadających konkretnym czynnościom (jak “Kopiuj”, “Wytnij”, “Wyślij”, “Drukuj”, itd.) — może to oznaczać użycie wzorca Polecenie. Takie klasy powinny implementować ten sam interfejs/klasę abstrakcyjną. Polecenia mogą samodzielnie implementować poszczególne czynności lub delegować zadania osobnym obiektom — zwanym odbiorcami. Ostatnim elementem układanki jest znalezienie obiektu wywołującego — będzie to klasa przyjmująca obiekty-polecenia w charakterze parametrów swoich metod lub konstruktora.

Polecenia edytora tekstu oraz funkcjonalność ‘cofnij’

Edytor tekstu w poniższym przykładzie tworzy nowe obiekty-polecenia przy okazji każdej interakcji użytkownika z programem. Po wykonaniu swoich zadań, polecenie trafia na stos stanowiący historię poleceń.

Aby cofnąć czynność, aplikacja pobiera ostatnio uruchomione polecenie z historii i albo wykonuje odwrotną czynność, albo przywraca wcześniejszy stan edytora, zapisany przez to polecenie.

commands

commands/Command.java: Abstrakcyjne bazowe polecenie

package refactoring_guru.command.example.commands; import refactoring_guru.command.example.editor.Editor; public abstract class Command { public Editor editor; private String backup; Command(Editor editor) { this.editor = editor; } void backup() { backup = editor.textField.getText(); } public void undo() { editor.textField.setText(backup); } public abstract boolean execute(); } 

commands/CopyCommand.java: Kopiuj zaznaczony tekst do schowka

package refactoring_guru.command.example.commands; import refactoring_guru.command.example.editor.Editor; public class CopyCommand extends Command { public CopyCommand(Editor editor) { super(editor); } @Override public boolean execute() { editor.clipboard = editor.textField.getSelectedText(); return false; } } 

commands/PasteCommand.java: Wklej tekst ze schowka

package refactoring_guru.command.example.commands; import refactoring_guru.command.example.editor.Editor; public class PasteCommand extends Command { public PasteCommand(Editor editor) { super(editor); } @Override public boolean execute() { if (editor.clipboard == null || editor.clipboard.isEmpty()) return false; backup(); editor.textField.insert(editor.clipboard, editor.textField.getCaretPosition()); return true; } } 

commands/CutCommand.java: Wytnij tekst i umieść w schowku

package refactoring_guru.command.example.commands; import refactoring_guru.command.example.editor.Editor; public class CutCommand extends Command { public CutCommand(Editor editor) { super(editor); } @Override public boolean execute() { if (editor.textField.getSelectedText().isEmpty()) return false; backup(); String source = editor.textField.getText(); editor.clipboard = editor.textField.getSelectedText(); editor.textField.setText(cutString(source)); return true; } private String cutString(String source) { String start = source.substring(0, editor.textField.getSelectionStart()); String end = source.substring(editor.textField.getSelectionEnd()); return start + end; } } 

commands/CommandHistory.java: Historia poleceń

package refactoring_guru.command.example.commands; import java.util.Stack; public class CommandHistory { private Stack<Command> history = new Stack<>(); public void push(Command c) { history.push(c); } public Command pop() { return history.pop(); } public boolean isEmpty() { return history.isEmpty(); } } 

editor

editor/Editor.java: GUI edytora tekstu

package refactoring_guru.command.example.editor; import refactoring_guru.command.example.commands.*; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class Editor { public JTextArea textField; public String clipboard; private CommandHistory history = new CommandHistory(); public void init() { JFrame frame = new JFrame("Text editor (type & use buttons, Luke!)"); JPanel content = new JPanel(); frame.setContentPane(content); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS)); textField = new JTextArea(); textField.setLineWrap(true); content.add(textField); JPanel buttons = new JPanel(new FlowLayout(FlowLayout.CENTER)); JButton ctrlC = new JButton("Ctrl+C"); JButton ctrlX = new JButton("Ctrl+X"); JButton ctrlV = new JButton("Ctrl+V"); JButton ctrlZ = new JButton("Ctrl+Z"); Editor editor = this; ctrlC.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { executeCommand(new CopyCommand(editor)); } }); ctrlX.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { executeCommand(new CutCommand(editor)); } }); ctrlV.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { executeCommand(new PasteCommand(editor)); } }); ctrlZ.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { undo(); } }); buttons.add(ctrlC); buttons.add(ctrlX); buttons.add(ctrlV); buttons.add(ctrlZ); content.add(buttons); frame.setSize(450, 200); frame.setLocationRelativeTo(null); frame.setVisible(true); } private void executeCommand(Command command) { if (command.execute()) { history.push(command); } } private void undo() { if (history.isEmpty()) return; Command command = history.pop(); if (command != null) { command.undo(); } } } 

Demo.java: Kod klienta

package refactoring_guru.command.example; import refactoring_guru.command.example.editor.Editor; public class Demo { public static void main(String[] args) { Editor editor = new Editor(); editor.init(); } } 

OutputDemo.png: Wynik działania

Polecenie w innych językach

Polecenie w języku C# Polecenie w języku C++ Polecenie w języku Go Polecenie w języku PHP Polecenie w języku Python Polecenie w języku Ruby Polecenie w języku Rust Polecenie w języku Swift Polecenie w języku TypeScript