Java Design Pattern cainiao series (iii) models and implementations of the modifier Pattern
Decorator mode: dynamically attaches responsibility to objects. To expand a function, the Decorator provides an alternative solution that is more flexible than inheritance. For the modifier mode, it is actually a kind of packaging, so I prefer to call it a kind of packaging. I/O streams in Java, which we used frequently, use the modifier mode. For example, BufferedReader br = new BufferedReader (new InputStreamReader (new FileInputStream (file1); here, file1 is the target object, while BufferedReader and InputStreamReader are called packaging classes. The following is an example:
I. UML Model Diagram
Ii. Code Implementation
/*** Disable modification and open extension. ** Unified interface */interface Filterable {public void filter ();}/*** target class */class Filter implements Filterable {@ Overridepublic void filter () {System. out. println (core filtering method of the target class ...);}} /*** the DecoratorForFilter1 packaging class implements the same interface as the target class --> woven into Log */class implements Filterable {private Filterable filterable; public DecoratorForFilter1 (Filterable filterable) {this. filterable = filterable;} private void beforeMethod () {System. out. println (DecoratorForFilter1 --> execute the core filter method before execution);} private void afterMethod () {System. out. println (DecoratorForFilter1 --> execute the core filter method after execution);} @ Overridepublic void filter () {beforeMethod (); filterable. filter (); afterMethod () ;}}/*** DecoratorForFilter2: the same interface is implemented for the packaging class and the target class --> Log x/class DecoratorForFilter2 implements Filterable {private Filterable filterable; public DecoratorForFilter2 (Filterable filterable) {this. filterable = filterable;} private void beforeMethod () {System. out. println (DecoratorForFilter2 --> execute the core filter method before execution);} private void afterMethod () {System. out. println (DecoratorForFilter2 --> execute the core filter method after execution);} @ Overridepublic void filter () {beforeMethod (); filterable. filter (); afterMethod () ;}}/*** client Test class ** @ author Leo */public class Test {public static void main (String [] args) {/*** target object */Filterable targetObj = new Filter ();/*** wrap the object (wrap the target object) */Filterable decorObj = new DecoratorForFilter1 (new DecoratorForFilter2 (targetObj);/***** Business Method After packaging */decorObj. filter ();}}
Output:
DecoratorForFilter1 --> execute the core filter method before execution
DecoratorForFilter2 --> run the core filter method before execution
Core filtering method of the target class...
DecoratorForFilter2 --> execute the core filter method after execution
DecoratorForFilter1 --> execute the core filter method after execution
Iii. application scenarios (personal opinions only) I/O, filters, interceptors, and AOP
Iv. Summary
Through the input Log, we can see that the output process is actually the process of "unpacking" The packaging class, just as the packaging bags are split layer by layer.
Design principles: 1) multi-purpose combination, less inheritance. 2) It is open to the extension and closed to the modification.