Reader small image

You're reading from  Advanced Python Programming - Second Edition

Product typeBook
Published inMar 2022
PublisherPackt
ISBN-139781801814010
Edition2nd Edition
Right arrow
Author (1)
Quan Nguyen
Quan Nguyen
author image
Quan Nguyen

Quan Nguyen is a Python programmer and machine learning enthusiast. He is interested in solving decision-making problems under uncertainty. Quan has authored several books on Python programming and scientific computing. He is currently pursuing a Ph.D. degree in computer science at Washington University in St. Louis, researching Bayesian methods in machine learning.
Read more about Quan Nguyen

Right arrow

Chapter 25: The Command Pattern

In this chapter, we will cover the command pattern. Using this design pattern, we can encapsulate an operation, such as copy and paste, as an object. The command pattern is also great for grouping multiple commands. It's useful for implementing macros, multilevel undoing, and transactions. Throughout our discussions, we will learn about the idea of treating an operation as an object and use this command mindset to handle application transactions.

We will discuss the following:

  • Understanding the command pattern
  • Real-world examples
  • Use cases
  • Implementation

Technical requirements

The code files for this chapter can be accessed through this link: https://github.com/PacktPublishing/Advanced-Python-Programming-Second-Edition/tree/main/Chapter25.

Understanding the command pattern

Most applications nowadays have an undo operation. It is hard to imagine, but undo did not exist in any software for many years. Undo was introduced in 1974 (j.mp/wiundo), but Fortran and Lisp, two programming languages that are still widely used, were created in 1957 and 1958, respectively (j.mp/proghist)! The user had no easy way to fix a mistake. I wouldn't like to have been an application user during those years.

Enough with the history! We want to know how we can implement the undo functionality in our applications, and since you have read the title of this chapter, you already know which design pattern is recommended to implement undo: the command pattern.

The command design pattern helps us encapsulate an operation (undo, redo, copy, paste, and so forth) as an object. What this simply means is that we create a class that contains all the logic and the methods required to implement the operation. The advantages of doing this are as...

Real-world examples

When we go to a restaurant for dinner, we give the order to the waiter. The order pad (usually paper) that they use to write the order is an example of a command. After writing the order, the waiter places it in the queue that is executed by the cook. Each check is independent and can be used to execute many different commands, for example, one command for each item that will be cooked.

As you would expect, we also have several examples in software. Here are two I can think of:

  • PyQt is the Python binding of the QT toolkit. PyQt contains a QAction class that models an action as a command. Extra optional information is supported for every action, such as description, tooltip, or shortcut (j.mp/qaction).
  • Git Cola (j.mp/git-cola), a Git GUI written in Python, uses the Command pattern to modify the model, amend a commit, apply a different election, check out, and so forth (j.mp/git-cola-code).

Let's now be more general and discuss when the...

Use cases

Many developers use the undo example as the only use case of the command pattern. The truth is that undo is the killer feature of the command pattern. However, the command pattern can actually do much more (j.mp/commddp):

  • GUI buttons and menu items: The PyQt example that was already mentioned uses the command pattern to implement actions on buttons and menu items.
  • Other operations: Apart from undo, commands can be used to implement any operation. A few examples are cut, copy, paste, redo, and capitalize text.
  • Transactional behavior and logging: Transactional behavior and logging are important to keep a persistent log of changes. They are used by operating systems to recover from system crashes, relational databases to implement transactions, filesystems to implement snapshots, and installers (wizards) to revert canceled installations.
  • Macros: By macros, in this case, we mean a sequence of actions that can be recorded and executed on demand at any point...

Implementation

In this section, we will use the command pattern to implement the most basic file utilities:

  • Creating a file and optionally writing text (a string) to it
  • Reading the contents of a file
  • Renaming a file
  • Deleting a file

We will not implement these utilities from scratch, since Python already offers good implementations of them in the os module. What we want is to add an extra abstraction level on top of them so that they can be treated as commands. By doing this, we get all the advantages offered by commands.

From the operations shown, renaming a file and creating a file support undo. Deleting a file and reading the contents of a file do not support undo. Undo can actually be implemented on delete file operations. One technique is to use a special trash/wastebasket directory that stores all the deleted files so that they can be restored when the user requests them. This is the default behavior used on all modern desktop environments and is...

Summary

In this chapter, we covered the command pattern. Using this design pattern, we can encapsulate an operation, such as copy and paste, as an object. Using this pattern, we can execute a command whenever we want, and not necessarily at creation time, while the client code that executes a command does not need to know any details about how it is implemented. Moreover, we can group commands and execute them in a specific order.

To demonstrate command, we implemented some basic file utilities on top of Python's os module. Our utilities supported undo and had a uniform interface, which makes grouping commands easy.

The next chapter covers the Observer pattern.

Questions

The answers to these questions can be found in the Assessments section at the end of the book:

  1. What are the high-level benefits of the command pattern?
  2. From the perspective of the client of an application, how is the command pattern specifically useful?
  3. How is the command pattern implemented in the Python example of file management?
lock icon
The rest of the chapter is locked
You have been reading a chapter from
Advanced Python Programming - Second Edition
Published in: Mar 2022Publisher: PacktISBN-13: 9781801814010
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Quan Nguyen

Quan Nguyen is a Python programmer and machine learning enthusiast. He is interested in solving decision-making problems under uncertainty. Quan has authored several books on Python programming and scientific computing. He is currently pursuing a Ph.D. degree in computer science at Washington University in St. Louis, researching Bayesian methods in machine learning.
Read more about Quan Nguyen