Objective
The decoration mode is also a kind of structure pattern, the main purpose is to use adornment mode to reduce the coupling degree relative to the inheritance relation between class and class. There are many parts of the JDK used in the decorative mode, such as Java's various I/O streams, javax.swing package, some of the graphical interface component enhancements and other places have used the decorative mode.
Decoration Mode definition
The decorative pattern is defined as the ability to dynamically extend an object without changing the original class file and without using inheritance . Decoration mode is achieved by creating a wrapper object, which is to wrap the real object with decorations.
Example
Or the usual, for example, the birthday cake for friends and family, and then the birthday cake has a variety of accessories to decorate, such as: cream, fruit, cheese, chocolate and so on. If you do not have these accessories to decorate, is the ordinary chicken cake. So we can use the process of making cakes to implement the code:
First define the Cake interface
/***/Publicinterface cakegoods {/** * Show Cake * /void showcake () ; /** * display price * /BigDecimal showprice ();}
The specific chicken cake
/*** Chicken Cake*/@Data Public classSpongecakeImplementscakegoods{//Cake Name PrivateString name; //Cake Price PrivateBigDecimal Price; Publicspongecake (String name,bigdecimal price) { This. Name =name; This. Price =Price ; } /*** Show Cake*/@Override Public voidShowcake () {System.out.println ("The" + This. name+ "Cake"); } /*** Display Price*/@Override PublicBigDecimal Showprice () {return This. Price; }}
Abstract class of Excipients
/*** Abstract class of excipients*/ Public Abstract classDecoratorImplementscakegoods{PrivateCakegoods Cakegoods; Public voidsetcakegoods (Cakegoods cakegoods) { This. Cakegoods =Cakegoods; } /*** Show Cake*/@Override Public voidShowcake () {cakegoods.showcake (); } /*** Display Price*/@Override PublicBigDecimal Showprice () {returnCakegoods.showprice (); }}
Fruit
/*** Fruit*/ Public classFruitsextendsDecorator {/*** Show Cake*/@Override Public voidShowcake () {System.out.print ("Add Fruit"); Super. Showcake (); } /*** Display Price*/@Override PublicBigDecimal Showprice () {return NewBigDecimal (20.00). Add (Super. Showprice ()); }}
Cream
/*** Cream*/ Public classCreamextendsDecorator {/*** Show Cake*/@Override Public voidShowcake () {System.out.print ("Add Cream"); Super. Showcake (); } /*** Display Price*/@Override PublicBigDecimal Showprice () {return NewBigDecimal (15.00). Add (Super. Showprice ()); }}
Test
Public classTests { Public Static voidMain (string[] args) {//Making chicken CakesCakegoods Cakegoods =NewSpongecake ("Birthday Blessing",NewBigDecimal (50)); Decorator Cream=NewCream (); Decorator Fruits=NewFruits (); //Add Creamcream.setcakegoods (fruits); //Add Fruitfruits.setcakegoods (cakegoods); //ShowCream.showcake (); System.out.println ("The Price is:" +cream.showprice () + "Yuan"); }}
Operation Result:
The price of the birthday blessing cake with cream and fruit is: 85 RMB
The above example of the cake is used in the decoration mode, in the chicken cake spongecake to expand the time did not affect its original class structure, and did not use the relationship of inheritance, but eventually achieved the purpose of decoration. Let's analyze the decorative pattern is made up of those parts.
Structure of the decoration mode
The structure of the decorative pattern is shown above, consisting mainly of the following characters.
Abstract Component Role : (Cakegoods) defines an abstract interface to standardize the objects that are ready to be decorated and to be inputstram/outputstream and reader/writer in the IO stream in Java.
The specific component role : (Spongecake) defines a class that will be decorated, equivalent to the FileOutputStream and fileinputstream within the I/O stream.
Decorative Role : (decorator) defines a reference that holds the role of an abstract component and defines an interface that remains with the abstract component. Equivalent to the Filteroutputstream and filterinputstream inside I/O.
Specific Decorative roles : (Fruits and cream) responsible for each component role object plus corresponding decorations, equivalent to the I/O flow in the Bufferedoutputstream, Bufferedinputstream.
In use, you must extend the functionality of the cakegoods, but we extend the cakegoods by fruits and cream, so you can extend the functionality without having to know the presence of cakegoods in relation to decorator.
Summarize the advantages of decoration mode
- For extending the functionality of an object, the adornment mode is more flexible than inheritance and does not result in a dramatic increase in the number of classes. For example, if you want to add a jujube cakes or a chocolate accessory without modifying the existing code, just use JuJube cakes as a subclass of Cakegoods and a subclass of decorator.
- You can dynamically extend the functionality of an object.
- An object can be decorated many times, by using different decorative classes and the arrangement of these decorative classes, you can create a lot of different behavior of the combination, to get more powerful objects.
- The concrete component class and the concrete adornment class can change independently, the user may add the new concrete component class and the concrete adornment class according to the need, the original class library code does not need to change, conforms to "the opening and closing principle".
Disadvantages of Decoration mode
- Using the decorative mode for system design will produce a lot of small objects, the difference is that they are connected to each other in a different way, rather than their class or property values are different, a large number of small objects will inevitably occupy more system resources, on a certain program to affect the performance of the program.
- Decoration mode provides a more flexible solution than inheritance, but also means more error-prone than inheritance, troubleshooting is also very difficult, for many decorative objects, debugging may need to search for errors in the step-by-step troubleshooting, more cumbersome.
Applicable scenarios
Add responsibilities to a single object in a dynamic, transparent manner without affecting other objects.
Decorative mode can be used when the system cannot be extended in an inherited way or inherited is not conducive to system expansion and maintenance. There are two main types of cases where inheritance is not possible: the first class is a large number of independent extensions in the system, in order to support the combination of each extension or extension will produce a large number of subclasses, resulting in an explosive increase in the number of subclasses; the second is because the class is defined as not inherited (such as the final class in the Java language)
Refueling, to cheer for themselves, overcome inertia!!!
To learn more about design patterns, see the Java Design Patterns Learning record-gof design pattern Overview.
Java Design pattern Learning record-decoration mode