The model of software Design (ii) Decorator mode

Source: Internet
Author: User
Tags prepare static class wrapper

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.

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.