Java and pattern 26-9th-decoration pattern

Source: Internet
Author: User
Document directory
  • Source code
  • Source code

Decoration mode, also known as wrapper mode. The decoration mode extends the object functions in a transparent way to the client. It is an alternative to the inheritance relationship.

Decoration mode structure

  The decoration mode dynamically attaches more responsibilities to an object in a transparent manner to the customer. In other words, the client does not think that objects are different before and after decoration. The decoration mode can extend the functions of objects without creating more child classes.

The decoration mode class diagram is as follows:

Roles in the decoration mode include:

Abstract component role:An abstract interface is provided to standardize the objects preparing to receive additional responsibilities.

Concretecomponent role:Defines a class to receive additional responsibilities.

Decorator role:An instance that holds a component object and defines an interface consistent with the abstract Component Interface.

Specific Decoration (ConcreteDecorator) role:Attaches the attached responsibility to the component object.

Source code

Abstract component role

Package COM. bankht. decorator;/*** @ Author: -AK47 * @ Creation Time: 09:21:22, December 26, ** @ Class description: abstract component role */public interface component {public void sampleoperation ();}

Specific Component roles

Package COM. bankht. decorator;/*** @ Author: -AK47 * @ Creation Time: 09:22:05, December 26, ** @ Class description: specific Component role */public class concretecomponent implements component {@ overridepublic void sampleoperation () {// todo auto-generated method stub // write relevant business code }}

Decoration role

Package COM. bankht. decorator;/*** @ Author: -AK47 * @ Creation Time: 09:23:03, December 26, ** @ Class description: decoration role */public class decorator implements component {private component; public decorator (Component component) {This. component = component ;}@ overridepublic void sampleoperation () {// delegate to component. sampleoperation ();}}

Specific decoration roles

Package COM. bankht. decorator;/*** @ Author: -AK47 * @ Creation Time: 09:23:34, December 26, ** @ Class description: specific decoration role */public class concretedecoratora extends decorator {public concretedecoratora (Component component) {super (Component) ;}@ overridepublic void sampleoperation () {super. sampleoperation (); // write the relevant business code }}

 

Package COM. bankht. decorator;/*** @ Author: -AK47 * @ Creation Time: 09:23:34, December 26, ** @ Class description: specific decoration role */public class concretedecoratorb extends decorator {public concretedecoratorb (Component component) {super (component);} @ overridepublic void sampleoperation () {super. sampleoperation (); // write the relevant business code }}
Example of Qi tiandasheng

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

In this example, the role of component is played by the famous Qi Tiansheng; the role of concretecomponent belongs to the master of dasheng, that is, Zookeeper himself; the role of decorator is played by the 7th change of dasheng. The role of concretedecorator is the change of fish and birds.

Source code

The abstract component role "" interface defines a move () method, which must be implemented by all the specific component classes and decoration classes.

Package COM. bankht. decorator. wukong;/*** @ Author: -AK47 * @ Creation Time: 09:28:23, December 26, ** @ Class description: The abstract component role "" interface defines a move () method, which must be implemented by all the specific component classes and decoration classes. * /// Grand Holy privilege public interface thegreatestsage {public void move ();}

 

Specific Component roles: "Big Sage"

Package COM. bankht. decorator. wukong;/*** @ Author: -AK47 * @ Creation Time: 09:28:50 ** @ Class description: the specific component role "" Contains classes */public class monkey implements thegreatestsage {@ overridepublic void move () {// code system. out. println ("monkey move ");}}

Abstract decoration role "72 changes"

Package COM. bankht. decorator. wukong;/*** @ Author: -AK47 * @ Creation Time: 09:29:24 ** @ Class description: abstract decoration role "changed" */public class change implements thegreatestsage {private thegreatestsage Sage; Public change (thegreatestsage SAGE) {This. sage = Sage;} @ overridepublic void move () {// code sage. move ();}}

Specific decorative role "fish"

Package COM. bankht. decorator. wukong;/*** @ Author: -AK47 * @ Creation Time: 09:29:47 ** @ Class description: specific decoration role "fish" */public class fish extends Change {public fish (thegreatestsage SAGE) {super (SAGE) ;}@ overridepublic void move () {// code system. out. println ("fish move ");}}

Specific decorative role "bird"

Package COM. bankht. decorator. wukong;/*** @ Author: -AK47 * @ Creation Time: 09:30:11 ** @ Class description: specific decoration role "bird" */public class bird extends Change {public bird (thegreatestsage SAGE) {super (SAGE) ;}@ overridepublic void move () {// code system. out. println ("bird move ");}}

Client type

Package COM. bankht. decorator. wukong;/*** @ Author: -AK47 * @ Creation Time: 09:30:32 ** @ Class description: client class */public class client {public static void main (string [] ARGs) {thegreatestsage sage = new monkey (); // The first method is thegreatestsage bird = new bird (SAGE); thegreatestsage fish = new fish (BIRD ); // method 2 // thegreatestsage fish = new fish (New Bird (SAGE); fish. move (); bird. move ();}}

 

The "big Sage" is a concretecomponent class, while the "Birds" and "fish" are decorative classes. You need to describe the "Big Sage", that is, the "zookeeper" instance.

In the above example, the system has decorated a saint from a bird to a bird (adding the functionality of the bird to the bird ), then, the birds were decorated as a fish (adding the functions of the fish to the slogan + birds and getting the slogan + bird + fish ).

As shown in, the major changes first attach the functionality of the bird to zookeeper, and then the functionality of the fish to the birds.

  

Simplified decoration Mode

  In most cases, the implementation of the decoration mode is simpler than the schematic example given above.

If there is only one concretecomponent class, consider removing the abstract component class (Interface) and using decorator as a concretecomponent subclass. As shown in:

If there is only one concretedecorator class, there is no need to create a separate decorator class. Instead, you can combine the responsibilities of decorator and concretedecorator into one class. This can be done even if there are only two concretedecorator classes. As shown in:

Transparency requirements

The decoration mode requires the program to declare a variable of the concretecomponent type instead of a variable of the component type.

In the example of Sun Wukong, all the changes made by Sun Wukong must always be treated as Sun Wukong. If he regards the old sun as a fish instead of an old Sun, he will be cheated by the old sun, this should not happen. The following method is correct:

TheGreatestSage sage = new Monkey();TheGreatestSage bird = new Bird(sage);

 

The following method is incorrect:

 

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

 

Translucent decoration Mode

However, the pure decoration mode is hard to find. The purpose of the decoration mode is to enhance the performance of the classes to be considered without changing the interface. When enhancing performance, new public methods are often required. Even in Sun dasheng's system, new methods are needed. For example, qitian dasheng does not have the ability to fly, but birds do. This means that the bird should have a new fly () method. For example, Qi tianda Sheng class does not have the ability to swim, but the fish have, which means that there should be a new swim () method in the fish class.

This leads to the implementation of most decorative modes 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 the variables of the concretedecorator type, so that the methods in the concretedecorator class can be called:

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 purpose of the adapter mode is to change the interface of the class to be considered. You can also modify one or more methods or add new methods to enhance or change the functions of the class to be considered. Most of the decoration modes are actually translucent decoration modes, which are also called semi-decoration and semi-adapter mode.

Advantages of decoration Mode

(1) The purpose of the relationship between the decoration mode and inheritance is to expand the object functions, but the decoration mode can provide more flexibility than inheritance. The decoration mode allows the system to dynamically "Paste" a desired "decoration", or remove an unwanted "decoration ". The inheritance relationship is different. The inheritance relationship is static, which is determined before the system runs.

(2) by using different specific decorative classes and the arrangement and combination of these decorative classes, designers can create a combination of many different behaviors.

Disadvantages of decoration Mode

Because the decorative mode is used, there are a few categories that are needed than the inheritance relationship. Use fewer classes, of course, make the design easier. However, on the other hand, the use of decoration mode will produce more objects than the use of inheritance relationships. More objects make it difficult to query errors, especially those objects look very similar.

 

Application of design patterns in Java I/O Libraries

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

Because the Java I/O Library requires a lot of combinations of performance, if these performances are implemented using an inherited method, each combination requires a class, this will cause a large number of duplicate classes. If the decorative mode is used, the number of classes will be greatly reduced, and the performance repetition can be minimized. Therefore, the decoration mode is the basic mode of the Java I/O library.

The object structure of the Java I/O Library is as follows. Because there are many Java I/O objects, only the inputstream part is drawn.

We can see that:

Abstract component role:Played by inputstream. This is an abstract class that provides unified interfaces for various subtypes.

Concretecomponent role:Played by bytearrayinputstream, fileinputstream, pipedinputstream, stringbufferinputstream, and other classes. They implement the interfaces specified by the abstract component role.

Decorator role:Played by filterinputstream. It implements the interface specified by inputstream.

The specific Decoration (concretedecorator) role:Played by several classes: bufferedinputstream, datainputstream, and linenumberinputstream and pushbackinputstream.

 

Translucent decoration Mode

Both the decoration mode and the adapter mode are "wrapper pattern". They both encapsulate other objects for the purpose of design, but their forms are quite different.

The ideal decoration mode requires that the interface of the specific component role and decoration role be exactly the same as that of the abstract component role while enhancing the function of the decorated object. The adapter mode is not. Generally, the adapter mode does not require enhancement of the functions of the source object, but changes the interface of the source object to match the target interface.

There are two decorative modes: transparent and translucent. The difference between the two is whether the interface of the decorative role is completely consistent with that of the abstract component role. The transparent decoration mode is the ideal decoration mode. The interface of the specific component role and decoration role must be exactly the same as that of the abstract component role. On the contrary, if the interface of the decoration role is different from the interface of the abstract component role, that is, the interface of the decoration role is wider than the interface of the abstract component role, the decoration role has actually become an adapter role, this decorative mode is acceptable, as shown in.

In the adapter mode, the interfaces of the adapter class usually overlap with the interfaces of the target class, but they are often not the same. In other words, the interface of the adapter class is wider than the interface of the decorated target class.

Obviously, the translucent decoration mode is actually a gray area between the adapter mode and the decoration mode. If you combine the decoration mode and the adapter mode into a "Packaging mode", the translucent decoration mode can be representative of the "Packaging mode" after the merger.

Decoration mode in inputstream type

The decoration mode in the inputstream type is translucent. To illustrate this, take a look at the source code of the inputstream of the abstract component role in the decoration mode. This abstract class declares nine methods and provides eight implementations. The other is an abstract method, which must be implemented by sub-classes.

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() throws IOException {}        public synchronized void mark(int readlimit) {}        public synchronized void reset() throws IOException {}    public boolean markSupported() {}}

  

The following is the source code of the abstract decoration role filterinputstream class as the decoration mode. It can be seen that the interfaces of filterinputstream are exactly the same as those of inputstream. That is to say, this step is still in line with the decoration mode.

 

public class FilterInputStream extends InputStream {    protected FilterInputStream(InputStream in) {}        public 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() throws IOException {}    public synchronized void mark(int readlimit) {}    public synchronized void reset() throws IOException {}    public boolean markSupported() {}}

The following is the source code of the decoration 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 unread(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) throws IOException {}    public boolean markSupported() {}    public synchronized void mark(int readlimit) {}     public synchronized void reset() throws IOException {}    public synchronized void close() throws IOException {}}

Check the source code and you will find that this decoration class provides additional methods unread (), which means pushbackinputstream is a translucent decoration class. In other words, it undermines the requirements of the ideal decorative model. If the client holds a reference to the inputstream object, if the actual type of the In is pushbackinputstream, as long as the client does not need to use the unread () method, the client generally has no problem. However, if the client must use this method, it must undergo downward type conversion. This method can be called only after the in type is converted to pushbackinputstream. However, this type conversion means that the client must know it
The reference is to point to an object of the pushbackinputstream type. This undermines the original intention to use the decoration mode.

There is always a gap between the real world and the theory. Pure decorative patterns are hard to find in real systems. Generally, this translucent decoration mode is used.

 

The following is a simple example of how to use an I/O Stream to read file content.

Public class iotest {public static void main (string [] ARGs) throws ioexception {// stream Read File datainputstream Dis = NULL; try {Dis = new datainputstream (New bufferedinputstream (New fileinputstream ("test.txt"); // read the object content byte [] BS = new byte [dis. available ()]; DIS. read (BS); string content = new string (BS); system. out. println (content);} finally {dis. close ();}}}

 

Observe the above Code and you will find that the innermost layer is a fileinputstream object, and then pass it to a bufferedinputstream object, which is processed by bufferedinputstream, the processed object is then passed to the datainputstream object for processing. This process is actually the assembly process of the decorator. The fileinputstream object is equivalent to the original decorated object, the bufferedinputstream object and datainputstream object are equivalent to the decorator.

 

 

Related Article

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.