Welcome everybody to put forward the opinion, discuss together!
Reprint please indicate is quoted in http://blog.csdn.net/chenyujing1234
Example code: (Compilation tool: Eclipse)
http://www.rayfile.com/zh-cn/files/1291b5bd-9418-11e1-b6a1-0015c55db73d/
Reference books: << software tips-----Design patterns That's something >>
The decorator pattern (decorator [' dekəreitə] pattren) is the ability to dynamically extend an object without altering the original class file and using inheritance, by creating a wrapper object that is
Decorate to wrap the real object.
There are several things to note when using Decorator mode: (1) decorative objects have the same interface as real objects. This allows the client object to interact with the decorated object in the same way as the real object. (2) The decorative object contains a reference to a real object. (3) The decorated object accepts all requests from the client and forwards the requests to the real object. (4) Decorative objects can add additional functionality before or after forwarding these requests. This ensures that, at run time, additional functionality can be added externally without modifying the structure of a given object. In object-oriented design, the function extension of a given class is usually implemented through inheritance, however, the adorner pattern does not require subclasses and can dynamically extend functionality as the application runs. 1, a generalized analysis of the production process of dyed steamed bread: (1) The need to produce a normal steamed bun; (2) in order to save costs (not using cornmeal), the use of dyeing agents to add to the normal steamed bread, (3) through the mixer and finally produce "corn steamed bread."
/**
* Steamed Bread Processing Interface
* *
@author * */public
interface Ibread {
//Prepare material public
void Prepair ();
//and face public
void Kneadflour ();
Steamed steamed bun public
Void steamed ();
/**
* Processing Steamed bread Method * * Public
void process ();
}
/**
* The realization of normal steamed bun * * @author * *
/Public
class Normalbread implements Ibread {
//preparation material Public
void Prepair () {
System.out.println ("Preparation of flour, water and baking powder ...");
}
Dough and public
void Kneadflour () {
System.out.println ("face ...");
}
Steamed steamed bun public
Void steamed () {
System.out.println ("Steamed steamed bun ...") The fragrant steamed bread was baked. ");
}
/**
* Processing Steamed bread Method * * Public
void process () {
//preparation Material
Prepair ();
and
Kneadflour ();
Steamed steamed Bun
steamed ();
}
/**
* Dyed Corn Steamed bread
*
* @author
* * *
/Public
class Cornbread extends Normalbread {
//black-hearted traders began to dye c7/>public void Paint () {
System.out.println ("Add lemon coloring agent ...");
The surface method of overloading the parent class
@Override public
void Kneadflour () {
///After adding the dye to the flour to begin the dough
this.paint ();
and
Super.kneadflour ();
}
/** *
Sweet Bread
* *
* @author
* */public
class Sweetbread extends Normalbread {
//black-hearted traders Start adding sweet vegetarian public
void paint () {
System.out.println ("Add sweet vegetarian ...");
}
The surface method of overloading the parent class
@Override public
void Kneadflour () {
///After adding the sweet element to the flour to begin the dough
this.paint ();
and
Super.kneadflour ();
}
We know that the type of steamed bread is a lot of, now the black-hearted traders want to produce "sweet corn buns", how to do the rebuke. You may want to say "use inheritance" is not OK. Then create a steamed bun, inherit the normal steamed bread class. Admittedly, this is good to do, can achieve the requirements. However, reflected on the class diagram is a more subclass, if there are other types of steamed bread, to inherit it. In that case the class is going to explode, the huge inheritance class diagram. Inheritance is a two-point disadvantage: (1) The parent class is too dependent, and the parent-class modification affects the behavior of the subclass. (2) Can not reuse existing classes, resulting in too many subclasses.
2, below we use the decorator pattern to realize the dyeing steamed bread instance. Using the adorner's static class diagram, the structure is shown in the diagram. (1) In order to decorate the normal steamed bun Normalbread, we need a normal steamed bun the same abstract adornment: Abstractbread, this kind and the normal steamed bread class normalbread to realize Ibread steamed bread interface, The difference is that the abstract class contains a private property of the Ibread interface type bread, and then the external Ibread interface type object is passed in by constructing the method.
/** *
Abstract Decorator *
* @author
* *
/Public
abstract class Abstractbread implements Ibread {
// Store incoming Ibread objects
private final ibread bread;
Public abstractbread (Ibread bread) {
this.bread = bread;
}
Prepare material public
void Prepair () {
this.bread.prepair ();
}
Dough and public
void Kneadflour () {
this.bread.kneadFlour ();
}
Steamed steamed bun public
Void steamed () {
this.bread.steamed ();
}
Processing steamed bread method public
void process () {
prepair ();
Kneadflour ();
Steamed ();
}
The Abstractbread class satisfies the adorner's requirements: it has the same interface as the real object, contains a reference to a real object, accepts all requests from the client, and forwards these requests to the real object; You can add additional functionality. (2) Create the decorator. A, the creation of dye decoration----corndecorator. Create dye Decorator "Corndecorator", Inherit Abstractbread, contain modify behavior: Add lemon yellow coloring agent.
/**
* Dyed Corn steamed bun * *
@author
*
*
/public class Corndecorator extends Abstractbread {
//construction method C7/>public corndecorator (ibread bread) {
super (bread);
}
Unscrupulous traders began to dye the public
void paint () {
System.out.println ("Add lemon stain ...");
}
The surface method of overloading the parent class
@Override public
void Kneadflour () {
///After adding the dye to the flour to begin the dough
this.paint ();
and
Super.kneadflour ();
}
This is the same as the contents of the cornbread class mentioned above, just one more construct method. B, create sweet-----sweetdecorator of mutual decoration
/** *
Sweet Vegetarian Steamed bun * * * @author * * * * *
/Public
class Sweetdecorator extends Abstractbread {
/ /constructor method public
sweetdecorator (ibread bread) {
super (bread);
}
Unscrupulous traders start adding sweet vegetarian public
void paint () {
System.out.println ("Add sweet vegetarian ...");
}
The surface method of overloading the parent class
@Override public
void Kneadflour () {
///After adding the sweet element to the flour to begin the dough
this.paint ();
and
Super.kneadflour ();
}
C, the production of sweet corn buns. First create a normal steamed bread, and then use sweet vegetarian decorative steamed bread, then use lemon yellow coloring agent to decorate steamed bread, finally processing steamed bread.
/** *
Client application
* * @author * */public
class Client {
/**
* @param
args * * public static void Main (string[] args) {
//production of decorative steamed bun
System.out.println ("\n==== began to decorate steamed bun ...") ");
Create common examples of normal steamed buns
//This is what we need to wrap (decorate) The object instance
ibread normalbread = new Normalbread ();
The following began to decorate the normal steamed bread ...
//Use sweet-element decorative steamed bun
normalbread = new Sweetdecorator (normalbread);
Use lemon yellow coloring agent to decorate steamed bun
normalbread = new Corndecorator (normalbread);
Production of steamed bread Information
normalbread.process ();
System.out.println ("= = the end of decorative steamed bun ...") ");
}
}
Run Result:
= = start decorating steamed bun ...
prepare flour, water and baking powder
... Add lemon yellow coloring agent
... Add Sweet Vegetarian
... and noodles ...
Steamed steamed bun ... The fragrant steamed bread was baked.
= = The end of decorative steamed bread ...
Maybe you will feel strange, we first use the sweet element, then use the coloring agent, should first print sweet pigment, and then print the coloring agent. Not surprisingly, this is not contradictory, because the decorator is equivalent to the original object of the packaging, this is like a gift box, the most inside is a most common carton, and then use the general paper packaging, and finally use a more beautiful packaging paper packaging, we first saw the most beautiful wrapper, followed by the general wrapping.
3. Design Principles
(1) package change part
Design Patterns are the best explanation for encapsulation changes, regardless of which design pattern is directed at the "Change" part of the software, and then
encapsulate these "change" parts with abstraction. The advantage of using abstractions is that it provides great convenience for software extensions.
It is very flexible to express the dependencies between objects in a way that the class inheritance and combination are reasonably utilized in the decorator pattern.
Part of the "change" in the decorator pattern application is the extension of the component, which is completely isolated from the decorator so that we can arbitrarily change the decorator and the decorated person. (2) "open-closed" principle
When we need to extend and add new functionality to the component, we just need to implement a particular decorator, which is exactly incremental modification,
It has no impact on the original software functional structure, and is completely transparent to the client app, without concern for internal implementation details. (3) oriented to abstract programming, do not face to implement programming
In the decorator mode, the decorator role is the abstract class implementation, the benefit of the abstract programming is to play a good interface isolation role. When used,
What we're working on is abstract class references, which show object-oriented abstraction programming. (4) Prioritize the use of object combinations, rather than class inheritance.
The most successful decorator pattern is the rational use of object composition, which expands the functionality of the component flexibly, all of which are obtained by combining rather than inheriting.
This fundamentally determines the high cohesion and the low coupling. 4, the use of occasions (1) When we need to dynamically add a new function or responsibility for an existing object, we can consider using the decorator mode;
(2) When the responsibilities of an object are constantly changing or often need to dynamically increase the responsibility, to avoid the change in order to adapt to increase the inheritance of child class extension, because this way will cause the child class expansion of the speed is too fast, difficult to control, at this time can use the adorner mode.
The client does not feel that the object is different before and after the decoration, and the decorator pattern can extend the function of the object without creating more subclasses, and the adorner pattern uses a subclass instance that was originally decorated.
Delegates the client's call to the adorner.
Let's look at the static class diagram of the decorator pattern. So that we have a clearer understanding of the decorator pattern.
A, the decorated person abstract component: is an interface or abstract class, is the core object of the definition.
In the decorator mode, there must be a core, the most original interface. This class is the base class where we need to decorate the class. In this case, the Ibread interface.
B, the decorated person concretely realizes concretecomponent: This is an implementation class of component class, we want to decorate is this concrete implementation class. In this case, the Normalbread
C, decorator decorator: is generally an abstract class. It has a reference to the component variable.
D, decorators realize ConcreteDecorator1 and ConcreteDecorator2.