Design Patterns教程-装饰器模式
装饰器模式表示 “动态地给对象添加灵活的额外职责”。
换句话说,装饰器模式使用组合而不是继承在运行时扩展对象的功能。
装饰器模式也称为 包装器(Wrapper)。
装饰器模式的优点
- 它比静态继承提供了更大的灵活性。
- 它增强了对象的可扩展性,因为更改是通过编码新类来完成的。
- 它简化了编码,使你可以从目标类开发一系列功能,而不是将所有行为编码到对象中。
装饰器模式的使用
适用于以下情况:
- 当你希望透明且动态地向对象添加职责,而不影响其他对象时。
- 当你希望向对象添加职责,并且未来可能会更改时。
- 当通过子类扩展功能已不再实用时。
装饰器模式的 UML:
实现上述 UML:
步骤 1
创建一个 Food 接口。
public interface Food {
public String prepareFood();
public double foodPrice();
}
// Food 接口结束。
步骤 2
创建一个实现 Food 接口并重写所有方法的 VegFood 类。
文件:VegFood.java
public class VegFood implements Food {
public String prepareFood() {
return "Veg Food";
}
public double foodPrice() {
return 50.0;
}
}
步骤 3
创建一个 FoodDecorator 抽象类,实现 Food 接口并重写所有方法,并具有装饰更多食物的能力。
文件:FoodDecorator.java
public abstract class FoodDecorator implements Food {
private Food newFood;
public FoodDecorator(Food newFood) {
this.newFood = newFood;
}
@Override
public String prepareFood() {
return newFood.prepareFood();
}
public double foodPrice() {
return newFood.foodPrice();
}
}
步骤 4
创建一个 NonVegFood 具体类,扩展 FoodDecorator 类并重写所有方法。
文件:NonVegFood.java
public class NonVegFood extends FoodDecorator {
public NonVegFood(Food newFood) {
super(newFood);
}
public String prepareFood() {
return super.prepareFood() + " With Roasted Chicken and Chicken Curry";
}
public double foodPrice() {
return super.foodPrice() + 150.0;
}
}
步骤 5
创建一个 ChineseFood 具体类,扩展 FoodDecorator 类并重写所有方法。
文件:ChineseFood.java
public class ChineseFood extends FoodDecorator {
public ChineseFood(Food newFood) {
super(newFood);
}
public String prepareFood() {
return super.prepareFood() + " With Fried Rice and Manchurian";
}
public double foodPrice() {
return super.foodPrice() + 65.0;
}
}
步骤 6
创建一个 DecoratorPatternCustomer 类,使用 Food 接口来确定客户想要哪种食物(装饰)。
文件:DecoratorPatternCustomer.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class DecoratorPatternCustomer {
private static int choice;
public static void main(String args[]) throws NumberFormatException, IOException {
do {
System.out.print("========= Food Menu ============ \n");
System.out.print(" 1. Vegetarian Food. \n");
System.out.print(" 2. Non-Vegetarian Food.\n");
System.out.print(" 3. Chinese Food. \n");
System.out.print(" 4. Exit \n");
System.out.print("Enter your choice: ");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
choice = Integer.parseInt(br.readLine());
switch (choice) {
case 1: {
VegFood vf = new VegFood();
System.out.println(vf.prepareFood());
System.out.println(vf.foodPrice());
}
break;
case 2: {
Food f1 = new NonVegFood(new VegFood());
System.out.println(f1.prepareFood());
System.out.println(f1.foodPrice());
}
break;
case 3: {
Food f2 = new ChineseFood(new VegFood());
System.out.println(f2.prepareFood());
System.out.println(f2.foodPrice());
}
break;
default: {
System.out.println("Other than these no food available");
}
return;
}
} while (choice != 4);
}
}
输出
========= Food Menu ============
1. Vegetarian Food.
2. Non-Vegetarian Food.
3. Chinese Food.
4. Exit
Enter your choice: 1
Veg Food
50.0
========= Food Menu ============
1. Vegetarian Food.
2. Non-Vegetarian Food.
3. Chinese Food.
4. Exit
Enter your choice: 2
Veg Food With Roasted Chicken and Chicken Curry
200.0
========= Food Menu ============
1. Vegetarian Food.
2. Non-Vegetarian Food.
3. Chinese Food.
4. Exit
Enter your choice: 3
Veg Food With Fried Rice and Manchurian
115.0
========= Food Menu ============
1. Vegetarian Food.
2. Non-Vegetarian Food.
3. Chinese Food.
4. Exit
Enter your choice: 4
Other than these no food available