Computer Science
Decorator Pattern
The Decorator Pattern is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. It is used to extend or modify the functionality of objects at runtime by wrapping them in an object of a decorator class.
Written by Perlego with AI-assistance
Related key terms
1 of 5
12 Key excerpts on "Decorator Pattern"
- eBook - ePub
An Atypical ASP.NET Core 5 Design Patterns Guide
A SOLID adventure into architectural principles, design patterns, .NET 5, and C#
- Carl-Hugo Marcotte(Author)
- 2020(Publication Date)
- Packt Publishing(Publisher)
Chapter 9 : Structural Patterns In this chapter, we'll explore four design patterns from the well-known Gang of Four (GoF). These are structural patterns that are used to create complex, flexible, and fine-grained classes. The following topics will be covered in this chapter:- Implementing the Decorator design pattern
- Implementing the Composite design pattern
- Implementing the Adapter design pattern
- Implementing the Façade design pattern
Implementing the Decorator design pattern
The Decorator Pattern allows us to extend objects at runtime while keeping responsibilities separated. It is a simple but powerful pattern. In this section, we'll explore how to implement this pattern in the traditional way, as well as how to leverage an open source tool named Scrutor to help us create powerful DI-ready decorators using .NET 5.Goal
The decorator's goal is to extend an existing object, at runtime, without changing its code. Moreover, the decorated object should not be aware that it is being decorated, leaving it as a great candidate for long-lived or complex systems that need to evolve. This pattern fits systems of all sizes.I often use this pattern to add flexibility and create adaptability to a program for next to no cost. In addition, small classes are easier to test, so the Decorator Pattern adds ease of testability into the mix, making it worth mastering.The Decorator Pattern makes it easier to encapsulate a single responsibility into multiple classes, instead of packing multiple responsibilities inside a single class.Design
A decorator class must both implement and use the interface that's being implemented by the decorated - eBook - ePub
Design Patterns in .NET
Mastering design patterns to write dynamic and effective .NET Code (English Edition)
- Timur Yaroshenko(Author)
- 2024(Publication Date)
- BPB Publications(Publisher)
In our case, the Bridge design pattern was used to manage pipeline logging capabilities. It provides the capability to use different classes for one purpose under a unified interface. It is helpful when you have multiple ways to solve one problem and want to switch between these ways without modifying the internals of your application.Decorator design pattern provides us with the capability to extend the base object with additional information. The base object goes through a line of decorators, and each adds additional information, thus extending it. And the most important part is that it can be done modularly with decoupling in mind.In the next chapter, we will explore behavioral design patterns. These patterns help with customization of behavior depending on a context. We will start with the template method, strategy, and chain of responsibility design patterns.Join our book’s Discord space Join the book’s Discord Workspace for Latest updates, Offers, Tech happenings around the world, New Release and Sessions with the Authors: https://discord.bpbonline.com - eBook - ePub
- Carl-Hugo Marcotte, Abdelhamid Zebdi(Authors)
- 2022(Publication Date)
- Packt Publishing(Publisher)
9
Structural Patterns
This chapter explores four design patterns from the well-known Gang of Four (GoF ). We use structural patterns to create complex, flexible, and fine-grained classes.Structural patterns help us build and organize complex object hierarchies in a maintainable fashion. They allow us to add behaviors to existing classes dynamically, whether we designed the initial system this way or as an afterthought that emerges out of necessity later in the program’s lifecycle.The following topics will be covered in this chapter:- Implementing the Decorator design pattern
- Implementing the Composite design pattern
- Implementing the Adapter design pattern
- Implementing the Façade design pattern
The first two patterns help us extend a class dynamically and efficiently manage a complex object structure. The last two help us adapt an interface to another or shield a complex system with a simple interface. Let’s begin!Implementing the Decorator design pattern
The Decorator Pattern allows us to extend objects at runtime while separating responsibilities. It is a simple but powerful pattern. In this section, we explore how to implement this pattern in the traditional way and how to leverage an open source tool named Scrutor to help us create powerful dependency injection-ready decorators using .NET.Goal
The decorator’s goal is to extend an existing object, at runtime, without changing its code. Moreover, the decorated object should not be aware that it is being decorated, leaving it as a great candidate for long-lived or complex systems that need to evolve. This pattern fits systems of all sizes.I often use this pattern to add flexibility and create adaptability to a program for next to no cost. In addition, small classes are easier to test, so the Decorator Pattern adds ease of testability into the mix, making it worth mastering. - No longer available |Learn more
Hands-On Design Patterns with Java
Learn design patterns that enable the building of large-scale software architectures
- Dr. Edward Lavieri(Author)
- 2019(Publication Date)
- Packt Publishing(Publisher)
The decorator design pattern allows us to assign responsibilities to an object without impacting the class. Without the decorator design pattern, we can assign responsibilities to objects through inheritance. A more streamlined approach is to use the decorator design pattern to assign additional responsibilities to specific objects. The key goal is to add the additional responsibility to objects dynamically and without impacting other objects.This design pattern is commonly used with graphical software that includes layering objects over one another. For example, building a Graphical User Interface (GUI ) or creating a Heads Up Display (HUD ) for a game.The decorator design pattern is occasionally referred to as a wrapper design pattern because the decorator essential wraps around the object and its dynamically created responsibilities.Passage contains an image
Use case
We will create a Printer Buffer Flusher Demo application to demonstrate how to implement the decorator design pattern. We have a flushBuffer() method that will not be modified. Functionality will be added using decorators. As you will see, the new functionality works without impacting the original flushBuffer() functions.Passage contains an image
UML class diagram
The following UML class diagram shows that our Printer Buffer Flusher Demo application includes a Printer class and a ConcretePrinter class that extends the Printer class. There are also two concrete decorator classes (ConcreteDecorator1 and ConcreteDecorator2) that extend the AbstractDecorator class:UML class diagram— decorator design pattern implementationAs illustrated here, the DecoratorDriver class is used to drive the application and contains the main() method.Passage contains an image
Programming the design pattern
Our Printer Buffer Flusher Demo application starts with an abstract Printer class that has an empty flushBuffer() method. Since it is an abstract method, it cannot have a method body. The following code shows this:abstract class Printer { public abstract void flushBuffer();}Next, we have a ConcretePrinter class that extends the Printer class. The flushBuffer() method is overridden and includes a contextual message that is printed to the console: - eBook - ePub
Python Object-Oriented Programming
Build robust and maintainable object-oriented Python applications and libraries, 4th Edition
- Steven F. Lott, Dusty Phillips(Authors)
- 2021(Publication Date)
- Packt Publishing(Publisher)
The second option is often a suitable alternative to multiple inheritance. We can construct a core object, and then create a decorator wrapping that core. Since the decorator object has the same interface as the core object, we can even wrap the new object in other decorators. Here's how it looks in a UML diagram:Figure 11.1: Decorator Pattern in UMLHere, Core and all the decorators implement a specific Interface . The dashed lines show "implements" or "realizes." The decorators maintain a reference to the core instance of that Interface via composition. When called, the decorator does some added processing before or after calling its wrapped interface. The wrapped object may be another decorator, or the core functionality. While multiple decorators may wrap each other, the object at the end of the chain of all those decorators provides the core functionality.It's essential that each of these is providing an implementation of a common feature. The intent is to provide a composition of processing steps from the various decorators, applied to the core. Often decorators are small, typically a function definition without any state.In Python, because of duck typing, we don't need to formalize these relationships with an official abstract interface definition. It's sufficient to make sure the classes have matching methods. In some cases, we may define a typing.Protocol as a type hint to help mypy reason about the relationships.A Decorator example
Let's look at an example from network programming. We want to build a small server that provides some data and a client that interacts with that server. The server will be simulating rolling complex handfuls of dice. The client will request a handful and wait for an answer that contains some random numbers.This example has two processes interacting via a TCP socket, a way to transmit bytes among computer systems. Sockets are created by a server that listens for connections. When a client attempts to connect to the socket, the server must accept the new connection, and the two processes can then pass bytes back and forth; for this example, there will be a request from client to server and a response from server to client. The TCP socket is part of the foundation for HTTP, around which the world wide web is built. - Frank Buschmann, Kevlin Henney, Douglas C. Schmidt(Authors)
- 2007(Publication Date)
- Wiley(Publisher)
Adaptation and Extension 431 A further group of four patterns deal with extending component implementations with additional functionality. I NTERCEPTOR supports the integration of out-of-band or extended control flow to the methods of a component, while V ISITOR supports the addition of new functions to an entire group of interconnected components. D ECORATOR supports the addition of new methods to a specific component, or to deco-rate any existing method with additional pre-and post-processing behavior, and E XECUTE -A ROUND O BJECT the addition of pre-and post-processing behavior to the methods and code blocks of a C++ object. D ECORATOR and E XECUTE -A ROUND O BJECT are similar in the sense that they wrap an object with pre-and post-processing behavior to be executed when specific methods are invoked, but they differ signif-icantly in their granularity and scope. Most obviously, D ECORATOR is a general-purpose pattern, whereas E XECUTE -A ROUND O BJECT is a C++ idiom. The other difference is that D ECORATOR can wrap only entire methods of a component with additional pre-and post-processing, whereas E XECUTE -A ROUND O BJECT can also wrap specific code blocks within a method. The diagrams below outline how the four patterns that provide func-tional extensions to components integrate with our pattern language for distributed computing. Encapsulated implementation Requestor Explicit Interface Interceptor Invoker Intercepting Filter Invocation Interceptor Context Object control flow extensions interceptor types Observer interceptor notification interceptor interface accessing client context- eBook - ePub
- Alexey Soshin, Anton Arhipov(Authors)
- 2022(Publication Date)
- Packt Publishing(Publisher)
Chapter 3 : Understanding Structural PatternsThis chapter covers structural patterns in Kotlin . In general, structural patterns deal with relationships between objects .We'll discuss how to extend the functionality of our objects without producing complex class hierarchies. We'll also discuss how to adapt to changes in the future or fix some of the design decisions taken in the past, as well as how to reduce the memory footprint of our program.In this chapter, we will cover the following patterns:- Decorator
- Adapter
- Bridge
- Composite
- Facade
- Flyweight
- Proxy
Technical requirements
The requirements for this chapter are the same as the previous chapters—you'll need IntelliJ IDEA and the JDK .You can find the code files for this chapter on GitHub at https://github.com/PacktPublishing/Kotlin-Design-Patterns-and-Best-Practices/tree/main/Chapter03 .Decorator
In the previous chapter, we discussed the Prototype design pattern, which allows us to create instances of classes with slightly (or not so slightly) different data. This raises a question:What if we want to create a set of classes that all have slightly different behavior?Well, since functions in Kotlin are first-class citizens (which we will explain in this chapter), you could use the Prototype design pattern to achieve this aim. After all, creating a set of classes with slightly different behavior is what JavaScript does successfully. But the goal of this chapter is to discuss another approach to the same problem. After all, design patterns are all about approaches - No longer available |Learn more
- Pethuru Raj Chelliah, Harihara Subramanian, Anupama Murali, Dr. Kayarvizhy N(Authors)
- 2017(Publication Date)
- Packt Publishing(Publisher)
The structural class pattern uses inheritance to compose interfaces or implementations, and structural object patterns advocate ways to compose objects and realize the new functionality. Some focus areas of Structural design pattern are as follows:- Providing a uniform abstraction of different interfaces (Adapter)
- Changing the composition at runtime and providing flexibility of object composition; otherwise, it is impossible with static class composition
- Ensuring efficiency and consistency by sharing objects
- Adding object responsibility dynamically
Passage contains an image
Adapter class (wrapper)
Convert one interface of a class into another interface that the client wanted. In other words, the adapter makes heterogeneous classes work together: - eBook - PDF
.NET 7 Design Patterns In-Depth
Enhance code efficiency and maintainability with .NET Design Patterns (English Edition)
- Vahid Farahmandian(Author)
- 2023(Publication Date)
- BPB Publications(Publisher)
Consequences: Disadvantages • Removing a Decorator has some complications. • Code debugging process becomes more complicated. Applicability: • When we need to add a feature dynamically and subtly to a class and at the same time, we do not want to affect the previous objects. • When it is not possible to add new functionality to the class through inheritance. 108 .NET 7 Design Patterns In-Depth Related patterns: Some of the following design patterns are not related to Decorator design pattern, but in order to implement this design pattern, checking the following design patterns will be useful: • Strategy • Composite • Chain of responsibility • Adapter • Proxy Facade In this section, the facade design pattern is introduced and analyzed, according to the structure presented in GoF design patterns section in Chapter 1, Introduction to Design Patterns. Name: Facade Classification: Structural design patterns Also known as: --- Intent This design pattern tries to facilitate communication with different components of a system by providing a simple interface. Motivation, Structure, Implementation, and Sample code: In Figure 3.8 to use different components of the system, users are directly connected with these components, which increases the complexity. The Facade design pattern tries to manage this complexity by providing a simple interface, so that the user does not get involved in communication complications: Structural Design Patterns 109 Figure 3.8: Interactions in system without the presence of Facade Therefore, in the presence of the Facade design pattern, the Figure 3.8 becomes as follows: Figure 3.9: Interactions in system with presence of Façade 110 .NET 7 Design Patterns In-Depth In order to clarify the issue, pay attention to the following scenario: Suppose there is a need in which the necessary infrastructure is needed to inquire about plane tickets from different airlines. - eBook - PDF
- Scott A. Whitmire(Author)
- 2022(Publication Date)
- Springer(Publisher)
The redesign made the work order code much less complicated. 4.8 DECORATIVE MODIFICATIONS There are times when you want part of a design component to behave slightly differently. There are two ways you can do this: create a new function for each set of behaviors (which almost requires a form of method overloading), or use a Decorator or State pattern [9]. A decorator (Figure 4.12) adds new functionality to an object of a class without modifying the class itself (this object-oriented technique is a bit more difficult to replicate in other programming styles, but it can be done). To create a decorator, create an abstract class or structure that defines the name and sig- nature of the method who’s behavior will change. Design the function that uses this behavior to accept the decorator. Split out the function from your original design component into sub- types of the decorator, one for each set of behaviors. At runtime, substitute the subtype with the desired behavior in place of the decorator. 80 4. ENGINEER DELIBERATELY Work order Engineered beam . . . Architectural beam . . . Work Order item length:int Figure 4.11: Work order using bridge pattern. Component <> Decorator Decoration 1 Decoration 2 Figure 4.12: Decorator Pattern [9]. Some languages, such as Python, support custom decorators for functions. With some work, you can use this technique instead of the object-oriented method. When dealing with medical images, the DICOM standard is not really standard. There are four or five MRI scanner manufacturers, and each makes proprietary changes to the standard that can seriously mess up your ability to read and process the resulting images. Among those who deal with medical images on a regular basis, it is well known that nearly all software that processes DICOM images have separate paths through the logic based on the manufacturer of the source scanner. Even the best tools fail if the manufacturer is unknown. - eBook - PDF
Handbook Of Software Engineering And Knowledge Engineering, Vol 2: Emerging Technologies
Volume II: Emerging Technologies
- Shi-kuo Chang(Author)
- 2002(Publication Date)
- World Scientific(Publisher)
They still remain the most widely used kind of software patterns in practical developments. 3.1. Objectives and scope Design patterns are “simple and elegant solutions to specific problems in object- oriented software design” [18]. They capture static and dynamic structure of these solutions in a consistent and easily applied form. They contain knowledge and experience that underlies many redesign and recoding efforts of developers that 652 V. Devedzac have struggled to achieve greater reuse and flexibility in their software. Design patterns show generalized, domain-independent solutions of stereotypical problems that can be used many times without ever doing it the same way twice. Exam- ples of such problems include representation of part-whole hierarchies, dynamic attachment of additional responsibilities to an object, accessing the elements of an aggregate object sequentially without exposing its underlying representation, and many more. Software designers have discovered dozens of design patterns so far (see the URLs at the end of the chapter, as well as [Gamma et al, 19941, [19], and [22]). It is possible to use design patterns in object-oriented software development in any application domain by adapting the general design solutions that they prescribe to the problems in specific application domains. 3.2. Examples The pattern description format used in this section follows the one from Fig. 3. However, due to space limitations, some sections from that template are omitted. As the first example, consider the Builder pattern [18,19] already described informally in the Introductory section. It has no alternative names. Classification and intent. Builder is a creational design pattern. Its intent is to help separate the construction of a complex object from its representation. Such a separation makes it possible to create different representations by the same con- struction process. - eBook - PDF
- MATT ZANDSTRA(Author)
- 2016(Publication Date)
- Apress(Publisher)
You can see the class diagram for this example in Figure 10-5 . CHAPTER 10 ■ PATTERNS FOR FLEXIBLE OBJECT PROGRAMMING 227 This model is very extensible. You can add new decorators and components very easily. With lots of decorators, you can build very flexible structures at runtime. The component class, Plains in this case, can be significantly modified in many ways without the need to build the totality of the modifications into the class hierarchy. In plain English, this means you can have a polluted Plains object that has diamonds, without having to create a PollutedDiamondPlains object. The Decorator Pattern builds up pipelines that are very useful for creating filters. The java.io package makes great use of decorator classes. The client coder can combine decorator objects with core components to add filtering, buffering, compression, and so on to core methods like read() . My web request example can also be developed into a configurable pipeline. Here’s a simple implementation that uses the Decorator Pattern: // listing 10.28 class RequestHelper { } // listing 10.29 abstract class ProcessRequest { abstract public function process(RequestHelper $req); } // listing 10.30 class MainProcess extends ProcessRequest { public function process(RequestHelper $req) { print __CLASS__ . : doing something useful with requestn; } } Figure 10-5. The Decorator Pattern CHAPTER 10 ■ PATTERNS FOR FLEXIBLE OBJECT PROGRAMMING 228 // listing 10.31 abstract class DecorateProcess extends ProcessRequest { protected $processrequest; public function __construct(ProcessRequest $pr) { $this->processrequest = $pr; } } As before, we define an abstract superclass ( ProcessRequest ), a concrete component ( MainProcess ), and an abstract decorator ( DecorateProcess ). MainProcess::process() does nothing but report that it has been called. DecorateProcess stores a ProcessRequest object on behalf of its children.
Index pages curate the most relevant extracts from our library of academic textbooks. They’ve been created using an in-house natural language model (NLM), each adding context and meaning to key research topics.











