Responsibilities:
Dynamically add new functionality to an object.
The Decorator pattern is a technique used in place of inheritance to extend new functionality of an object without adding subclasses through inheritance.
Use the association relationship of objects instead of inheritance, which is more flexible and avoids the rapid expansion of the type system.
scenes to be used:
1. Input stream and output stream in IO stream
2. The graphical interface component function in the Swing package
3. In the Servlet API, the default implementation class of the Decorator design pattern of a request object is HttpServletRequestWrapper,
This class adds functionality to the request object.
4. In struts2, the processing of request, response and session objects.
Implementation details:
Component abstract component role:
Real objects and decorated objects have the same interface, so that client objects can interact with decorated objects in the same way as real objects
ConcreteComponent specific component role (real object): FileInputStream, FileOutputStream in the io stream
Decorator decoration role:
Holding a reference to an abstract component, the decorated object receives all client requests and forwards those requests to the real object. so
You can add new functionality before and after the real object is called.
ConcreteDecorator specific decoration role:
Responsible for adding new responsibilities to component objects.
Class Diagram:
Abstract component:
package com.gcxzflgl.decorator; /** * Abstract construction * @author Administrator * */ public interface ICar { void move(); } //ConcreteComponent concrete component role (real object) class Car implements ICar { @Override public void move() { System.out.println("Run on land!"); } } //Decorator decoration role class SuperCar implements ICar { protected ICar car; public SuperCar(ICar car) { super(); this.car = car; } @Override public void move() { car.move(); } } //ConcreteDecorator specific decoration role class FlyCar extends SuperCar { public FlyCar(ICar car) { super(car); } public void fly(){ System.out.println("Fly in the sky!"); } @Override public void move() { super.move(); fly(); } } //ConcreteDecorator specific decoration role class WaterCar extends SuperCar { public WaterCar(ICar car) { super(car); } public void swim(){ System.out.println("Water upstream!"); } @Override public void move() { super.move(); swim(); } } //ConcreteDecorator specific decoration role class AICar extends SuperCar { public AICar(ICar car) { super(car); } public void autoMove(){ System.out.println("Auto run!"); } @Override public void move() { super.move(); autoMove (); } }
Client call:
package com.gcxzflgl.decorator; public class Client { public static void main(String[] args) { Car car = new Car(); car.move(); System.out.println("Add new function, fly----------"); FlyCar flycar = new FlyCar(car); flycar.move(); System.out.println("Add new functions, swim in water---------"); WaterCar waterCar = new WaterCar(car); waterCar.move(); System.out.println("Add two new functions, flying, swimming in water-------"); WaterCar waterCar2 = new WaterCar(new FlyCar(car)); waterCar2.move(); } }
Summary: The decoration pattern is also called the wrapper pattern
The decoration pattern reduces the coupling degree of the system, can dynamically add or delete the responsibilities of objects, and make the concrete construction classes that need to be decorated and
Concrete decorator classes can be changed independently to add new concrete build classes and concrete decorator classes.
advantage:
Extending object functions is more flexible than inheritance and will not lead to a sharp increase in the number of classes
You can decorate an object multiple times to create a combination of different behaviors and get a more powerful object
The concrete construction class and concrete decoration class can be changed independently, and users can add their own new concrete construction subclasses and concrete decoration subclasses according to their needs.
shortcoming:
A lot of small objects are generated, and a large number of small objects occupy memory, which affects performance to a certain extent.
The decoration mode is prone to errors, and debugging and troubleshooting are more troublesome.