Design Pattern Learning Path-Decorator mode-Dynamic Extender

Source: Internet
Author: User

Learn the decorator pattern today.

First, look at the requirements.

A café needs to make an order system in order to match their beverage supply needs.

First there is a super class, a beverage class.

Package com.chris.decorator;

Public abstract class Beverage {
	String description = "Unkown beverage";

	Public String getdescription () {
		return description;
	}
	
	public abstract double Cost ();
}

He has a property, a description of the drink, two methods, one method is to return the description, and the other is an abstract method that returns the price of the drink.


Then we started doing things, creating an entity class like Mocha, inheriting the drink, and then adding the appropriate description and rewriting the cost () method.

Each drink is written in a class to inherit, such as distilled coffee, black coffee, latte, and so on.

Looks like there's no problem.


At this time, other needs come, when buying coffee, customers can ask to add a variety of spices to the coffee, such as steamed milk, soy milk, mocha or milk bubbles and so on.

Then we start experimenting differently.


First attempt:

According to the above idea, we create a new class for each of the different coffees, to inherit the superclass, and then to achieve our goal by returning different descriptions and prices.

For example: Black coffee, black coffee with steamed milk, black coffee with Gamoca, black coffee with steamed milk and mocha ..... Wait, wait, etc...

At this time we will find a problem, through the different combinations, we must be poor to lift all types, in order to improve the system, it will be "class explosion", in reality to maintain so many of the same species is very scary and stupid.


Since the first scenario is low, we start to consider other options

Second attempt:

We do this by adding properties to the superclass, steaming milk, mocha and so on. Then return whether you need to steam milk, whether you need a method such as Mocha.

In this way, by setting different properties, we can define different drinks, only need to set whether the need to steam milk, whether the need for Mocha and other fields on the line, and then through the selection of spices to calculate the price.

The plan seems to be more sensible than the above, requiring only basic beverage classes, at least not adding new classes due to the increase in seasoning.


But think about it, there seems to be something wrong, if you want to add a new seasoning, we also need to put this superclass properties and corresponding methods also modified.

This goes against an important principle of design patterns: classes should be developed for extensions and closed for modifications.


The third attempt:

Here we begin to introduce our decorator pattern.

Why the decorator, because we only need to build a drink object, you can use different spices to decorate him, and can be a layer of decoration,

Finally, the cost () method is called to add the price dynamics of the seasoning by relying on the delegate.


How to understand, we look directly at the code, the previous superclass has already, I will not repeat the code.

Here, we need to add a new decorator class---Seasoning class, and inherit the beverage class, he has only one abstract method.

Package com.chris.decorator;

Public abstract class condiment extends beverage{public
	abstract String getdescription ();
}

Let's start with a coffee, espresso.

Package com.chris.decorator;

public class Espresso extends beverage{public
	
	Espresso () {
		description = "Espresso";
	}

	@Override public
	double Cost () {
		return;
	}
}

Then we will implement a specific seasoning, mocha.

Package com.chris.decorator;

public class Mocha extends condiment{
	beverage beverage;
	
	Public Mocha (Beverage beverage) {
		this.beverage = beverage;
	}

	@Override public
	String getdescription () {
		return beverage.getdescription () + "add Mocha";
	}

	@Override public
	double Cost () {
		return beverage.cost () + 3;
	}
}

The implementation of the seasoning is more critical, in the seasoning, we will have a beverage property, when the introduction of a drink, will be pre-treatment of the method of the drink, and return the final price of the current drink.

In this way, the seasoning is decorated with the incoming drink and can be decorated one layer at a level, and the final price is returned.

To test, we add a seasoning, milk foam.

Package com.chris.decorator;

public class Whip extends condiment {
	beverage beverage;

	Public Whip (Beverage beverage) {
		this.beverage = beverage;
	}

	@Override public
	String getdescription () {
		return beverage.getdescription () + "add Whip";
	}

	@Override public
	double Cost () {
		return beverage.cost () + 5;
	}
}

Here, we'll order a cup of espresso, and a cup of espresso with mocha and milk foam.

Package com.chris.decorator;

public class Coffeetestdrive {public
	static void Main (string[] args) {
		beverage beverage1 = new Espresso ();
		System.out.println (beverage1.getdescription () + "¥" + beverage1.cost ());
		
		Beverage Beverage2 = new Espresso ();
		Beverage2 = new Mocha (beverage2);
		Beverage2 = new Whip (beverage2);
		System.out.println (beverage2.getdescription () + "¥" + beverage2.cost ());
	}
}


Put the test results again, the money should be counted clear, the arithmetic should not be so bad.

espresso¥30.0
Espresso Add Mocha Add whip¥38.0


There is a lot of wood handy, let the code become elegant.

This is the decorator pattern: dynamically attaching responsibilities to objects, and to extend functionality, adorners provide a more resilient alternative than inheritance.


Using decorator mode allows us to dynamically expand new requirements without changing the original code.

In the JDK source code, FilterInputStream and Bufferedinputstream is the use of decorative mode, through a layer of decoration, will be inputstream the function of enrichment.


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.