The decorative pattern of Java and pattern

Source: Internet
Author: User

Decorative mode is also known as packaging (Wrapper) mode. Adornment mode extends the functionality of the object transparently to the client, and is an alternative to the inheritance relationship.

structure of the decoration mode

  Decorating mode dynamically attaches more responsibility to an object in a transparent manner to the customer. In other words, the client does not feel that the object is different before and after decorating. Adornment mode expands the functionality of an object without using the creation of more subclasses.

The class diagram for the decorating mode is as follows:

  

The roles in the decorating mode are:

abstract Component (Component) role: An abstract interface is given to standardize the objects that are ready to receive additional responsibilities.

Concrete Component (concretecomponent) Role: defines a class that will receive additional responsibilities.

decoration (Decorator) Role: holds an instance of a component (Component) object and defines an interface that is consistent with the abstract component interface.

specific decoration (concreteDecorator) Role: responsible for attaching the Component object "affixed" to the responsibility.

Source

Abstract component Roles

Public interface Component {public        void sampleoperation ();    }

Specific component roles

public class Concretecomponent implements Component {    @Override public    void Sampleoperation () {        //write related business code    }}

Decorative characters

public class Decorator implements component{    private Component Component;        Public Decorator (Component Component) {        this.component = Component;    }    @Override public    void Sampleoperation () {        //delegated to Widget        component.sampleoperation ();    }    }

Specific decorative characters

public class Concretedecoratora extends Decorator {public    Concretedecoratora (Component Component) {        super ( component);    }        @Override public    void Sampleoperation () {
Super.sampleoperation (); Write the relevant business code }}
public class Concretedecoratorb extends Decorator {public    concretedecoratorb (Component Component) {        super ( component);    }        @Override public    void Sampleoperation () {
     Super.sampleoperation (); Write the relevant business code }}

  

The example of the Holy Grail

There are 72 changes in the Sun Wukong, and each of his changes brings him an additional skill. When he becomes a fish, he can swim in the water, and when he becomes a bird, he can fly in the sky.

In this case, component's role is played by the famous concretecomponent, the role of which belongs to the Holy Buddha, Hozen himself, and decorator's role is played by the 72. And Concretedecorator's role is 72 changes like fish, birds and so on.

Source

Abstract component role the "Franzia-san" interface defines a move () method, which must be implemented by all concrete component classes and adornment classes.

The Zunhao public interface Thegreatestsage {public        void move ();

Concrete component Role "The Holy Buddha" Hozen class

public class Monkey implements Thegreatestsage {    @Override public    void Move () {        //code        System.out.println ("Monkey Move");}    }

Abstract decorative Character "72 change"

public class Change implements Thegreatestsage {    private thegreatestsage sage;        Public change (Thegreatestsage Sage) {        this.sage = sage;    }    @Override public    void Move () {        //code        Sage.move ();}    }

Specific decorative characters "fish"

public class Fish extends change {public        Fish (Thegreatestsage Sage) {        super (SAGE);    }    @Override public    void Move () {        //code        SYSTEM.OUT.PRINTLN ("Fish move");    }

Specific decorative characters "birds"

public class Bird extends change {public        Bird (Thegreatestsage Sage) {        super (SAGE);    }    @Override public    void Move () {        //code        SYSTEM.OUT.PRINTLN ("Bird move");}    }

Client class

public class Client {public    static void Main (string[] args) {        thegreatestsage sage = new Monkey ();        The first form of        thegreatestsage bird = new Bird (sage);        Thegreatestsage fish = new Fish (bird);        The second notation        //thegreatestsage fish = new Fish (new Bird (sage));        Fish.move ();     }}

"The Holy Buddha" is the Concretecomponent class, while the "Bird", "fish" is a decorative category. To decorate is "the Holy Buddha", also known as "Hozen" example.

In the above example, the system decorated the holy Man from a hozen into a bird (the function of the birds added to the Hozen body), and then decorate the birds into a fish (the function of the fish added to the Hozen + birds, got Hozen + birds + fish).

  

As shown, the change of the sage first attaches the function of the bird to the Hozen body, and then attaches the function of the fish to the Hozen + bird.

  

Simplification of decoration modes

  In most cases, the implementation of the decoration pattern is simpler than the illustrative example given above.

If there is only one Concretecomponent class, you can consider removing the abstract component Class (interface) and decorator as a concretecomponent subclass. As shown in the following:

If there is only one Concretedecorator class, then there is no need to create a separate decorator class, but you can combine the responsibilities of decorator and Concretedecorator into a single class. This can be done even in the case of only two concretedecorator classes. As shown in the following:

  

Requirements for transparency

The transparency of the decorative mode to the client requires the program not to declare a variable of type concretecomponent, but to declare a variable of type component.

In the case of Monkey King, we must always treat all the changes of the Sun Wukong as the Monkey King, and if the old sun turns into a fish as a fish, instead of the old sun, it will be cheated by the old sun, and this should not happen. The following is the right approach:

Thegreatestsage sage = new Monkey (); Thegreatestsage bird = new Bird (SAGE);

And the following is not the right approach:

Monkey sage = new Monkey (); Bird Bird = new Bird (SAGE);
Semi-transparent decorative pattern

However, purely decorative patterns are difficult to find. The decoration mode is intended to enhance the performance of the class under consideration without changing the interface. When it comes to enhancing performance, it's often necessary to create new, public methods. Even in Bajau systems, new methods are needed. For example, the Grand Saint class does not have the ability to fly, and the birds have. This means that the bird should have a new fly () method. For example, the Grand Saint class does not have the ability to swim, and fish have, which means there should be a new swim () method in the Fish class.

This led to the realization of most of the decorative patterns being "translucent" rather than completely transparent. In other words, allow the decoration mode to change the interface and add new methods. This means that the client can declare a variable of type concretedecorator so that it can invoke a method in the Concretedecorator class:

Thegreatestsage sage = new Monkey (); Bird Bird = new Bird (sage); Bird.fly ();

The translucent decoration mode is between the decoration mode and the adapter mode. The intent of the adapter pattern is to change the interface of the class being considered, or by rewriting one or more methods, or by adding new methods to enhance or change the functionality of the class being considered. Most of the decorative patterns are actually translucent decorative patterns, which are also known as semi-decorative, half-adapter modes.

Advantages of Decorative Mode

(1) The purpose of the adornment mode and the inheritance relation is to extend the function of the object, but the adornment mode can provide more flexibility than the inheritance. Decoration mode allows the system to dynamically decide to "paste" a desired "decoration", or to remove an unwanted "decoration". The inheritance relation is different, the inheritance relation is static, it decides before the system runs.

(2) Designers can create a combination of many different behaviors by using different decorative classes and arranging combinations of these decorations.

Disadvantages of Decoration mode

Because of the use of adornment mode, a smaller number of destination classes are required than using inheritance relationships. The use of fewer classes, of course, makes the design easier to carry out. However, on the other hand, using the adornment pattern produces more objects than using the inheritance relationship. More objects make it difficult to find errors, especially when they look alike.

Application of design Patterns in the Java I/O library

The most famous application of decorating patterns in the Java language is the design of the Java I/O standard library.

Because the Java I/O library requires a variety of combinations of performance, if these performance are implemented in an inherited way, then each combination requires a class, which results in a large number of performance-repeating classes appearing. In the case of decorative patterns, the number of classes is greatly reduced, and the repetition of performance can be minimized. Therefore, the decoration mode is the basic mode of the Java I/O library.

The object structure diagram for the Java I/O library is as follows, because of the large number of Java I/O objects, only the InputStream part is drawn.

As you can see:

abstract Component (Component) role: played by InputStream. This is an abstract class that provides a unified interface for each seed type.

specific component (concretecomponent) roles: Bytearrayinputstream, FileInputStream, PipedInputStream, StringBufferInputStream and other class play. They implement the interfaces specified by the abstract component role.

abstract Decoration (Decorator) role: played by FilterInputStream. It implements the interface specified by the InputStream.

specific decoration (concretedecorator) role: played by several classes, namely Bufferedinputstream, DataInputStream and two infrequently used classes Linenumberinputstream, Pushbackinputstream.

Semi-transparent decorative pattern

Both the adornment mode and the adapter mode are "wrapper mode (Wrapper pattern)", which are designed to encapsulate other objects, but their morphology is very different.

The ideal decoration mode is to enhance the function of the decorative object, and it requires the interface of the concrete component role and the decorative role to be identical with the interface of the abstract component role. The adapter mode is not, in general, the adapter pattern does not require enhancements to the source object's functionality, but it alters the interface of the source object to match the target interface.

The decorative mode is transparent and translucent, the difference between the interface of the decorative role and the interface of the abstract component role is exactly the same. The transparent decoration mode is the ideal decoration mode, which requires the interface of the specific component role and the decorative role to be identical to the interface of the abstract component role. Conversely, if the interface of the adornment role is inconsistent with the abstract component role interface, which means that the interface of the decorative role is wider than the interface of the abstract component role, the decorative role is actually an adapter role, and this adornment pattern is also acceptable, known as the "translucent" decorative pattern, as shown in.

In adapter mode, the interface of an adapter class usually overlaps with the interface of the target class, but it is often not identical. In other words, the interface of the adapter class is wider than the target class interface being decorated.

Obviously, the translucent decorative pattern is actually the gray area between the adapter mode and the decorative mode. If the adornment mode and the adapter mode are merged into a "wrapping mode", then the translucent decoration mode can become the representative of this merged "packing mode".

Decorative modes in the InputStream type

The adornment mode in the InputStream type is translucent. To illustrate this, take a look at the source code for the InputStream of the abstract component role as a decorative pattern. This abstract class declares nine methods and gives the implementation of eight of them, and the other is an abstract method that needs to be implemented by a subclass.

Public abstract class InputStream implements closeable {public    abstract int read () throws IOException;     public int read (byte b[]) throws IOException {} public    int read (byte b[], int off, int len) throws IOException {}    Public long Skip (long N) throws IOException {} public    int available () throws IOException {} public        void close () th Rows IOException {} public        synchronized void Mark (Int. readlimit) {} public        synchronized void Reset () throws Ioexce ption {} public    Boolean marksupported () {}}

  

The following is the source code for the FilterInputStream class as an abstract decorative role in decorative mode. As you can see, the FilterInputStream interface is exactly the same as the InputStream interface. That is, until this step, it is still in accordance with the decorative pattern.

public class FilterInputStream extends InputStream {    protected FilterInputStream (InputStream on) {} public        int Read () throws IOException {} public    int read (byte b[]) throws IOException {} public        int read (byte b[], int off, in T len) throws IOException {} public    long Skip (long N) throws IOException {} public    int available () throws Ioexcept Ion {} public    void Close () throws IOException {} public    synchronized void Mark (Int. readlimit) {} public    SYNCHR onized void Reset () throws IOException {} public    Boolean marksupported () {}}

  

The following is the source code for the specific decorative role pushbackinputstream.

public class Pushbackinputstream extends FilterInputStream {    private void Ensureopen () throws IOException {}        Public Pushbackinputstream (InputStream in, int size) {} public    Pushbackinputstream (InputStream in) {}    Public int read () throws IOException {} public    int read (byte[] B, int. off, int len) throws IOException {} public    void UNR EAD (int b) throws IOException {} public    void unread (byte[] B, int. off, int len) throws IOException {} public    void Unread (byte[] b) throws IOException {} public    int available () throws IOException {} public    long Skip (long N) throw S IOException {} public    Boolean marksupported () {} public    synchronized void Mark (Int. readlimit) {}     Public synchronized void Reset () throws IOException {} public    synchronized void Close () throws IOException {}}

Looking at the source code, you will find that this decoration class provides an additional method of unread (), which means that pushbackinputstream is a translucent decoration class. In other words, it destroys the ideal decorative pattern of the requirements. If the client holds a reference to a type InputStream object, then if the real type of in is Pushbackinputstream, then the client is generally no problem as long as the client does not need to use the unread () method. However, if the client must use this method, the downward type conversion must be performed. This method may not be called until the type of in has been converted to Pushbackinputstream. However, this type conversion means that the client must know that the reference it gets is pointing to an object of type Pushbackinputstream. This undermines the original intent to use the decorative pattern.

There is a gap between the real world and the theory. Purely decorative patterns are hard to find in real systems. In general, it is this translucent decorative pattern.

The following is a simple example of how to read the contents of a file using I/O streams.

public class Iotest {public    static void Main (string[] args) throws IOException {        //stream Read file        datainputstream di s = null;        try{            New DataInputStream (New Bufferedinputstream (New                            fileinputstream ("test.txt"            )); //Read file contents            byte[] bs = new byte[dis.available ()];            Dis.read (BS);            String content = new String (BS);            SYSTEM.OUT.PRINTLN (content);        } finally{            dis.close ();}}}    

Observing the above code, you will find the innermost layer is a FileInputStream object, and then pass it to a Bufferedinputstream object, after Bufferedinputstream processing, Then the processed object is passed to the DataInputStream object for processing, this process is actually the decorator assembly process, the FileInputStream object is equivalent to the original decorated object, Bufferedinputstream objects and DataInputStream objects are the equivalent of adorners.

The decorative pattern of Java and pattern

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.