知识库 知识库
首页
  • Hyperskill - Java

    • Java basic
    • Java OOP
    • 应知
    • 扩展
    • IO & Stream
    • Error & Exception
    • Algorithm & Data structure
    • Design pattern
    • Web
    • Spring boot
  • 练习题

    • 选择题 & 填空题
    • 代码题
  • Frank - Java与生活 (OOP)

    • 参考资料
    • Java基础
    • OOP上半部分
    • OOP下半部分
  • Frank - Java API进阶

    • Base API
    • Unit Test and main function
  • 学习笔记
  • 学习笔记

    • 数据库
  • Frank - MySQL删库跑路

    • 安装、连接、配置
    • 基本操作——数据库
    • 基本操作——表
    • 基本操作——数据
    • 数据类型
    • 列属性完整性
    • 数据库设计思维
    • 单表查询
    • 多表查询
  • 学习笔记

    • 其它
  • Frank - Linux现代方法

    • 必知
    • 命令
    • 技巧
  • 技术文档
  • Git
  • GitHub技巧
  • 前端
  • Khan Academy - 语法
  • Monthly
  • 阅读
  • Others
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 标签
  • 归档
GitHub (opens new window)

Jim FuckPPT

Java小学生
首页
  • Hyperskill - Java

    • Java basic
    • Java OOP
    • 应知
    • 扩展
    • IO & Stream
    • Error & Exception
    • Algorithm & Data structure
    • Design pattern
    • Web
    • Spring boot
  • 练习题

    • 选择题 & 填空题
    • 代码题
  • Frank - Java与生活 (OOP)

    • 参考资料
    • Java基础
    • OOP上半部分
    • OOP下半部分
  • Frank - Java API进阶

    • Base API
    • Unit Test and main function
  • 学习笔记
  • 学习笔记

    • 数据库
  • Frank - MySQL删库跑路

    • 安装、连接、配置
    • 基本操作——数据库
    • 基本操作——表
    • 基本操作——数据
    • 数据类型
    • 列属性完整性
    • 数据库设计思维
    • 单表查询
    • 多表查询
  • 学习笔记

    • 其它
  • Frank - Linux现代方法

    • 必知
    • 命令
    • 技巧
  • 技术文档
  • Git
  • GitHub技巧
  • 前端
  • Khan Academy - 语法
  • Monthly
  • 阅读
  • Others
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 标签
  • 归档
GitHub (opens new window)
  • Hyperskill - Java

    • Java basic

    • Java OOP

    • 应知

    • 扩展

    • IO & Stream

    • Error & Exception

    • Algorithm & Data structure

    • Design pattern

      • Theory:The concept of patterns
      • Theory:Structural of design patterns
      • Theory:Decorator pattern
        • Decorator design pattern
        • Decorator implementation
        • Decorator in pseudocode
        • Example of using decorator pattern
        • Conclusion
      • Theory:Decorator
    • Web

    • Spring boot

  • 练习题

  • Frank - Java与生活

  • Frank - Java API进阶

  • 学习笔记

  • Java
  • Hyperskill - Java
  • Design pattern
Jim
2022-10-17
目录

Theory:Decorator pattern

Many structural design patterns are needed to avoid unnecessary work and rewriting of code many times over. Usually, these patterns are made in such a way that you can avoid interfering with classes that were previously defined. The pattern that we will discuss in this topic is no different. This design pattern allows you to add new functions to objects, excluding changes to them. It's called the decorator design pattern.

# Decorator design pattern

A decorator is a structural design pattern that allows using special wrappers for objects, giving them new functionality while avoiding changes to their structure. This approach simplifies the coding process by delegating the implementation of new functions to other classes, instead of rewriting new object classes. So you can say that the main idea of this pattern is focused around wrapper objects. But what is a wrapper?

A wrapper (or decorator) is an object that works with your initial object in a way that alters its behavior. Wrapper shares the same interface and functions with that object. But, in case the user needs to call the initial object, the wrapper will pass the user's request through itself. In this process, there can be alteration on a result.

This approach is useful when you can't just modify your class and it will be hard to extend it with some child objects. Using a decorator, you can add new behaviors and even use multiple level wrappers, without touching any part of the existing class. But this can be a little tricky to implement, considering that you may end up being unable to remove some of the wrappers without ruining all of the code.

# Decorator implementation

Let's use the pizza-making process as an example. Cooks make pizza. They have abundant options for toppings and types of pizza. But in the end, a pizza is just some dough with something on top of it. So, if we try to depict the pizza-making process as code, we can create a new class for each pizza type. And if we want to create combinations of pizza toppings, we'll end up with a large number of classes which will complicate your work.

So, to avoid this unnecessary expansion of code, you can use the decorator pattern:

img

Using this pattern, we need to introduce these elements:

  • an interface that represents methods for basic pizza making;
  • a class that creates our pizza;
  • one base wrapper which will store our pizza object to combine it with our topping wrappers;
  • for this particular example, we'll have two wrappers for pizza toppings.

If we look at the resulting structure as a class diagram, it will look similar to this:

img

# Decorator in pseudocode

Now let's try to depict this pattern in pseudocode. First of all, we need to describe our Pizza interface:

interface Pizza is
  method MakePizza()
1
2

Here, we described all common methods for both our pizza maker and pizza wrapper. Next, we'll describe them as PlainPizza class and ToppingWrapper:

class PlainPizza implements Pizza is
  method cook() is
    return "Pizza"


class ToppingWrapper implements Pizza is
  field pizza: Pizza

  constructor pizzaWrapper(Pizza pizza)
    this.pizza = pizza

  method cook() is
    pizza.cook()
1
2
3
4
5
6
7
8
9
10
11
12
13

Both these classes will implement the Pizza interface. Our PlainPizza will return an object that represents a simple pizza that will be referenced within the ToppingWrapper class and then combined with our other wrappers.

Next, we'll define our Pepperoni and HotPepper wrappers:

class Pepperoni extends ToppingWrapper is
  method cook() is
    return pizza.cook() + "Pepperoni "

class HotPepper extends ToppingWrapper is
  method cook() is
    return pizza.cook() + "HotPepper "
1
2
3
4
5
6
7

As you can see, these wrappers will add some additional parts to our existing objects.

# Example of using decorator pattern

When we have all of our classes ready, we can call our topping wrappers in a client code, in order to add some new parts to our initial object:

//Client code:

Pizza pepperoni = new Pepperoni(new PlainPizza()) //decorate plain pizza
print("Description: " + pepperoni.cook())

//Output:
//Description: Pizza Pepperoni
1
2
3
4
5
6
7

If we call our PlainPizza constructor inside of the Pepperoni wrapper, we will have a modified object with additional parts. We can also put one wrapper inside of another. The result will look like this:

//Client code:

Pizza pepperoni = new Pepperoni(new PlainPizza()) //decorate plain pizza
Pizza hotPepperoni = new HotPepper(pepperoni) //decorate already decorated pizza
print("Description: " + hotPepperoni.cook())

//Output:
//Description: Pizza Pepperoni HotPepper
1
2
3
4
5
6
7
8

# Conclusion

Using the decorator design pattern, you can add new functions to existing code, while reducing the possibility of ruining it. By delegating all new functions and responsibilities to new wrapper objects, our code will be able to contain more variations of your objects. This could potentially simplify your coding process.

编辑 (opens new window)
#Pattern
上次更新: 2022/10/25, 17:57:56
Theory:Structural of design patterns
Theory:Decorator

← Theory:Structural of design patterns Theory:Decorator→

最近更新
01
《挪威的森林》
04-14
02
青钢影
04-14
03
Processing strings
02-18
更多文章>
Theme by Vdoing | Copyright © 2022-2023 Jim Frank | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式