Decorator pattern in Java

Introduction

Introducing the design patterns of [GoF](https://ja.wikipedia.org/wiki/Gang of for _ (Information Engineering)) ["Introduction to Design Patterns Learned in the Augmented and Revised Java Language"]( https://www.amazon.co.jp/ Augmented and revised edition Introduction to design patterns learned in Java language-Hiroshi Yuki / dp / 4797327030 / ref = pd_lpo_sbs_14_t_0? _ Encoding = UTF8 & psc = 1 & refRID = 2ZE4GPYNN55JGDR5QMHP) I will summarize about.

Decorator pattern

What is Decorator?

Translated into Japanese, it means "decorator". ** A pattern that expands functionality by steadily decorating the original object ** is called the ** Decorator pattern **. By applying this pattern, you can flexibly extend the functionality without changing the class from which it is extended.

Character

The Decorator pattern is used by the classes that appear in the class diagram below. image.png

Abstract class

Implementation class

Concrete example

As a concrete example, it will be explained based on the following class. image.png

Abstract class

-** Sponge Cake class **

SpongeCake.java


public abstract class SpongeCake {
	public abstract String getName(); //Get a name

	public abstract int getPrice(); //Get the price

	public void show() { //Show name and price
		System.out.println(getName() + ":" + getPrice() + "Circle");
	}
}

In the SpongeCake class, a method to get the name and price is defined as an abstract method, and a method to display them is defined as a concrete method. It's just a sponge cake with no decoration. The actual processing of the abstract class will be implemented in the subclass described later. There is nothing particularly difficult.

-** Decorator class **

Decorator.java


public abstract class Decorator extends SpongeCake {
	protected SpongeCake spongeCake; //Refers to the "contents" that this decorative frame is wrapped in

	protected Decorator(SpongeCake spongeCake) { //Specify "contents" as an argument when creating an instance
		this.spongeCake = spongeCake;
	}
}

The Decorator class inherits from the SpongeCake class above, but is an abstract class because it does not override the abstract method. ** The point is that the SpongeCake object to be decorated is held in the field and specified as an argument when the object is created by the constructor **.

Implementation class

-** ShortCake class **

ShortCake.java


public class ShortCake extends SpongeCake {

	@Override
	public String getName() { //Override the method to get the name of the parent class
		return "Shortcake";
	}

	@Override
	public int getPrice() { //Override the method to get the price of the parent class
		return 500;
	}

}

-** ChocolateCake class **

ChocolateCake.java


public class ChocolateCake extends SpongeCake {

	@Override
	public String getName() { //Override the method to get the name of the parent class
		return "Chocolate cake";
	}

	@Override
	public int getPrice() { //Override the method to get the price of the parent class
		return 700;
	}

}

The ShortCake class and the ChocolateCake class are implementation classes of the SpongeCake class. It is an image of a more concrete cake with a little decoration on the cake with only sponge. It overrides the abstract methods getName () and getPrice (), and returns the name and price respectively. There is nothing particularly difficult here either.

-** Strawberry Decorator class **

StrawberryDecorator.java


public class StrawberryDecorator extends Decorator {

	public StrawberryDecorator(SpongeCake spongeCake) { //Pass the decoration target in the constructor
		super(spongeCake);
	}

	@Override
	public String getName() { //Strawberries added to the beginning of the name of the contents
		return "Strawberry" + spongeCake.getName();
	}

	@Override
	public int getPrice() { //The price of the contents plus 100
		return spongeCake.getPrice() + 100;
	}

}

-** Banana Decorator class **

BananaDecorator.java


public class BananaDecorator extends Decorator {

	public BananaDecorator(SpongeCake spongeCake) { //Pass the decoration target in the constructor
		super(spongeCake);
	}

	@Override
	public String getName() { //Banana added to the beginning of the name of the contents
		return "banana" + spongeCake.getName();
	}

	@Override
	public int getPrice() { //The price of the contents plus 300
		return spongeCake.getPrice() + 300;
	}

}

The StrawberryDecorator class and the BananaDecorator class are implementation classes of the Decorator class. Add strawberries and bananas to the sponge cake (or its subclasses) specified in the constructor as decorations, respectively. Also, add the price in the same way.

The point is that ** the constructor argument is of type SpongeCake **. From this, we can see that the arguments that can be passed to the constructor are the SpongeCake class, or its subclasses ShortCake class and ChocolateCake class. Also, keep in mind that the Decorator class is also a subclass of the SpongeCake class. In other words, ** the StrawberryDecorator class and the BananaDecorator class that inherit from the Decorator class can be specified as arguments to the constructor of the StrawberryDecorator class that performs decoration **. This makes it possible to add more decoration to the decorated object.

Execution class

-** Main class **

Main.java


public class Main {
	public static void main(String[] args) {
		//Generation of shortcake
		SpongeCake s1 = new ShortCake();
		SpongeCake s2 = new StrawberryDecorator(s1);
		SpongeCake s3 = new BananaDecorator(s1);
		SpongeCake s4 = new StrawberryDecorator(new ShortCake());
		SpongeCake s5 = new StrawberryDecorator(new BananaDecorator(new ShortCake()));
		s1.show();
		s2.show();
		s3.show();
		s4.show();
		s5.show();
		System.out.println("--------------------------------------------");
		//Chocolate cake generation
		SpongeCake c1 = new ChocolateCake();
		SpongeCake c2 = new StrawberryDecorator(c1);
		SpongeCake c3 = new BananaDecorator(c1);
		SpongeCake c4 = new StrawberryDecorator(new ChocolateCake());
		SpongeCake c5 = new StrawberryDecorator(new BananaDecorator(new ChocolateCake()));
		c1.show();
		c2.show();
		c3.show();
		c4.show();
		c5.show();
	}
}

Instances of the ShortCake class and the ChocolateCake class are created and decorated respectively. The point is, as described in the description of the StrawberryDecorator class and the BananaDecorator class, ** Since the class to be decorated can be specified in the argument of the constructor, it is possible to perform multiple decorations. That is **.

Also,

4,5th line


SpongeCake s1 = new ShortCake();
SpongeCake s2 = new StrawberryDecorator(s1);

When

7th line


SpongeCake s4 = new StrawberryDecorator(new ShortCake());

Is just specifying the decoration target ShortCake in the constructor, and although the writing method is different, it is actually the same process.

Execution result

The result of executing Main.java is as follows. You can see that the original Short Cake and Chocolate Cake are being decorated more and more.

Execution result


Shortcake:500 yen
Strawberry shortcake:600 yen
Banana shortcake:800 yen
Strawberry shortcake:600 yen
Strawberry banana shortcake:900 yen
--------------------------------------------
Chocolate cake:700 yen
Strawberry chocolate cake:800 yen
Banana chocolate cake:1000 yen
Strawberry chocolate cake:800 yen
Strawberry banana chocolate cake:1100 yen

merit

The advantages of the Decorator pattern are: ** 1. ** Functions can be added without changing the inherited class. ** 2. ** Various functions can be added by combining the necessary parts.

Summary

I learned about the Decorator pattern, which adds decoration to objects one after another. The sample code is uploaded below, so please refer to it if you like.

-Decorator sample code

In addition, other design patterns are summarized below, so please refer to them as well.

-[Updated from time to time] Summary of design patterns in Java

References

-[Introduction to Design Patterns Learned in the Augmented and Revised Java Language](https://www.amazon.co.jp/ Introduction to Design Patterns Learned in the Augmented and Revised Java Language-Hiroshi Yuki / dp / 4797327030 / ref = pd_lpo_sbs_14_t_0? _Encoding = UTF8 & psc = 1 & refRID = 2ZE4GPYNN55JGDR5QMHP)

Recommended Posts

Decorator pattern in Java
Facade pattern in Java
Singleton pattern in Java
Flyweight pattern in Java
Iterator pattern in Java
Prototype pattern in Java
Proxy pattern in Java
Template Method pattern in Java
Chain of Responsibility pattern in Java
Design Pattern #Decorator
Learn the design pattern "Decorator" in Python
Singleton pattern in Python
Linux permissions in Java
Use DataFrame in Java
Write decorator in class
Understand the Decorator pattern by comparing JavaScript and Java code
Implement Table Driven Test in Java
Detect and process signals in Java.
Decorator 1
Implement the Singleton pattern in Python
Decorator 2
Implemented bubble sort in Java (BubbleSort)
GoF java design pattern rough summary
Decorator
Decorator
Overlapping regular expressions in Python and Java
Learn the design pattern "Prototype" in Python
Learn the design pattern "Builder" in Python
[Gang of Four] Design Pattern Learning --Decorator
Learn the design pattern "Observer" in Python
Learn the design pattern "Proxy" in Python
Apply Google Java Style formatter in IntelliJ
Learn the design pattern "Command" in Python
Differences in syntax between Python and Java
Get mail using Gmail API in Java
Learn the design pattern "Visitor" in Python
Implement a custom View Decorator in Pyramid
Decorator to avoid UnicodeEncodeError in Python 3 print ()
Learn the design pattern "Bridge" in Python
Learn the design pattern "Mediator" in Python
Learn the design pattern "Iterator" in Python
Learn the design pattern "Strategy" in Python
Learn the design pattern "Composite" in Python
Learn the design pattern "State" in Python
Let's run a Bash script in Java
Learn the design pattern "Adapter" in Python