003 -02- structural decorative patterns (the Decorator)

I. Overview

  Decoration (Decorator) mode, also known as packing mode. To extend the function of the object by means of a client in a transparent manner, it is an alternative to inheritance relationship. He is one of 23 design patterns, the English called Decorator Pattern, also known as the decorator pattern. In the case of decorative patterns without having to change the original class files and use inheritance, dynamically extend an object's function. It is by creating a wrapper object, which is decorated to wrap the real object.

  Without changing the original object, with an object to dynamically add some additional responsibilities.

1.1 application scenarios

  • Extension of a class or a class to add additional responsibilities
  • The object is added to a dynamic function, these functions can be dynamically re-revocation
  • The method can not be employed when generating a subclass be expanded. In one case, there may be a large number of separate extension to support each combination will produce a large number of sub-categories, so that the explosive growth in the number of subclasses. Another situation may be hidden because of the class definition, the class or subclass definition can not be used to generate.
  • It needs to be increased by a very large number of permutations and combinations of features of the basic functions is generated, so that the inheritance becomes impractical.

  For example: There is a very profound java reflected in the I / O class.

note,

  1. The multi-purpose compositions, less inheritance.
    Use design subclass inherits behavior is statically determined at compile time, and all subclasses will inherit the same behavior. However, if we can use a combination of behavioral practices extended object, it can dynamically expand at runtime.
  2. The class should be designed to be open for extension, but closed for modification.

1.2, the advantages and disadvantages

  advantage

    1. Decorator pattern with the purpose of inheritance is to extend the function of the object, but Decorator can provide more flexibility than inheritance.
    2. By using different permutations and combinations of these classes and decorative concrete decorative, designers can create a lot of combinations of different behaviors.

  Shortcoming

    1. This is more flexible than inherited characteristics, also means that more and more complexity.
    2. The decorative pattern can lead to many subcategories appear in the design, if overused, the program will become very complicated.
    3. The decorative pattern is programmed for the type of abstract component (Component). However, if you want to program for a specific component, you should rethink your application architecture, and decorators are appropriate. Of course, you can change the Component interface, adding new public behavior, to achieve "translucent," the decorator pattern. In a real project you want to make the best choice.
    4. produce small objects, large amount of memory occupied by objects small, affect the performance to some extent.

1.3, class diagram roles and responsibilities

  

  Roles and responsibilities decorative pattern:

  1, abstract component character (the Component) : an abstract interface, the interface is the parent class and the decoration of the decorated. (Car)

  2, the role of specific components (ConcreteComponent) : abstract class implemented components. (RunCar)

  3, abstract decorative role (Decorator) : contains a reference to the component and define a consistent and abstract component interfaces. (CarDecorator)

  4, specific decorative role (ConcreteDecorator) : implementation class is abstract decorative role. Responsible for specific decor. (FlyCarDecorator, SwimCarDecorator)

1.4 evolution

1.4.1, the original way

  Before, if we achieve such a function, build a variety of different functions of the car, it is implemented as follows:

  First, create a Car interface defines the basic functionality of all vehicles, it is to run run (), and methods to show their function show (),

Interface Car 

public interface Car {
    void show();

    void run();
}

  Then, create each specific vehicle to achieve Car Interface

  The basic functions of class - will run

public class RunCar implements Car {

    @Override
    public void show() {
        this.run();
    }

    @Override
    public void run() {
        System.out.println("可以跑");
    }
}

  Swim car

public class SwimCar implements Car {

    @Override
    public void show() {
        this.run();
        this.swim();
    }

    @Override
    public void run() {
        System.out.println("可以跑");
    }

    public void swim() {
        System.out.println("可以游泳");
    }
}

  Flying car

public class FlyCar implements Car {

    @Override
    public void show() {
        this.run();
        this.fly();
    }

    @Override
    public void run() {
        System.out.println("可以跑");
    }

    public void fly() {
        System.out.println("可以飞");
    }
}

  test

    @Test
    public void testCar() {
        //        Car car = new RunCar();
//        Car car = new FlyCar();
        Car car = new SwimCar();
        car.show();
    }

In this way, each new a vehicle, it is necessary to write a new subclass implement or extend other classes or interfaces, the equivalent of every new one function, it is necessary a new car.

1.4.2, decorative patterns

  First, create a new Car port, and a basic implementation of the Car class RunCar, because as long as the car must have run the function, both the same as above

  Then in New decorative, different functions built in different decorative

  1, a new decorative parent class that implements Car interface, providing a constructor argument, common methods show (), Car private member variables, and to provide them get (), set () method.

  Be sure to inherit Car, because after decoration, or a car

public abstract class CarDecorator implements Car {
    private Car car;

    public CarDecorator(Car car){
        this.car = car;
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    public abstract void show();
}

  2, for different decorative New decorative, abstract classes and inheritance CarDecorator

  (1) Swimming decorative covering abstract method, the new method in the unique

public class SwimCarDecorator extends CarDecorator {

    public SwimCarDecorator(Car car){
        super(car);
    }

    @Override
    public void show() {
        this.getCar().show();
        this.swim();
    }

    public void swim(){
        System.out.println("可以游泳");
    }

    @Override
    public void run() {
    }
}

  (2) Flight decoration

public class FlyCarDecorator extends CarDecorator {

    public FlyCarDecorator(Car car){
        super(car);
    }
    @Override
    public void show() {
        this.getCar().show();
        this.fly();
    }

    public void fly(){
        System.out.println("可以飞");
    }

    @Override
    public void run() {
    }
}

test

    @Test
    public void getCar() {
        Car car = new RunCar();
        Car swimCar = new SwimCarDecorator(car);
        swimCar.show();
    }

  In this way, it is not tantamount to, every new feature is a new car, but rather the basis of a RunCar, this is the most basic car, decorative equivalent on the basis of the basic car, add functionality, decorative this basic car.

  So be sure to inherit Car, because after decoration, or a car, we can directly Car swimCar = new SwimCarDecorator (car); with Car to create a variable. 

  Similarly, inheritance if every function should add a new sub-category, if a car already have a swim and fly function, then there also has a new swimming and flying Car, inheritance need in the new a sub-class also has two functions, while the decorative patterns do not need anything new, modified on the basis of RunCar can be twice. like this:

    @Test
    public void getCar2() {
        Car car = new RunCar();
        Car swimCar = new SwimCarDecorator(car);
        Car flySwimCar = new FlyCarDecorator(swimCar);
        flySwimCar.show();
    }

  This way, the final flySwimCar it also has the function of flight and swimming, which is the reason for Car decoration class inheritance, like this decoration can be used as parameters into the constructor.

   

1.5, the relevant design patterns

Decorator mode and proxy mode

  • Decorator Pattern: focus on the dynamic Add method on an object.
  • Proxy mode: attention to control access to objects, the proxy pattern proxy class can hide an object specific information on customers.
  • In use proxy mode time, often create an instance of an object in a proxy object. When we use the decorator pattern , the original object will usually as a parameter passed to the constructor decorator

Decorative pattern and adapter pattern

  • Decorative pattern and adapter pattern are called packing mode. In Decorator mode, with the decorator decorator can implement the same interface, or decorator is a subclass of the decorator. In the adapter mode, and is adapted to class the adaptation class have different interfaces, of course, also possible to have part of the interface coincide.

Second, the extension

2.1, jdk in Decorator

2.1.1、Java I/O-Reader与java.io.BufferedReader

reader

public abstract class Reader implements Readable, Closeable {
    protected Object lock;
    protected Reader() {
        this.lock = this;
    } 

BufferedReader

public class BufferedReader extends Reader {

    private Reader in;

    private char cb[];
    private int nChars, nextChar;

    private static final int INVALIDATED = -2;
    private static final int UNMARKED = -1;
    private int markedChar = UNMARKED;
    private int readAheadLimit = 0; 

    private boolean skipLF = false;

    private boolean markedSkipLF = false;

    private static int defaultCharBufferSize = 8192;
    private static int defaultExpectedLineLength = 80;
    public BufferedReader(Reader in, int sz) {

ReaderIs decorator, BufferedReaderis a decorator

2.1.2、Java I/O-InputStream与FilterInputStream

  

InputStreamIs decorator, FilterInputStreamis a decorator

The following is InputStream decorator pattern reflected Class FIG.

  

2.2, Spring application

2.2.1、TransactionAwareCacheDecorator

  

2.2.2、Spring-session

  org.springframework.session.web.http.SessionRepositoryFilter.SessionRepositoryRequestWrapper

2.3、tomcat

2.3.1、javax.servlet.ServletRequestWrapper

   

2.4、mybatis

2.4.1、org.apache.ibatis.cache.Cache

  

 

Guess you like

Origin www.cnblogs.com/bjlhx/p/11198949.html