装饰器模式表示 “动态地给对象添加灵活的额外职责”

换句话说,装饰器模式使用组合而不是继承在运行时扩展对象的功能。

装饰器模式也称为 包装器(Wrapper)

装饰器模式的优点

  • 它比静态继承提供了更大的灵活性。
  • 它增强了对象的可扩展性,因为更改是通过编码新类来完成的。
  • 它简化了编码,使你可以从目标类开发一系列功能,而不是将所有行为编码到对象中。

装饰器模式的使用

适用于以下情况:

  • 当你希望透明且动态地向对象添加职责,而不影响其他对象时。
  • 当你希望向对象添加职责,并且未来可能会更改时。
  • 当通过子类扩展功能已不再实用时。

装饰器模式的 UML:

4-1.jpg

实现上述 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

标签: Design Patterns, Design Patterns教程, 设计模式, 软件设计, 结构型模式, 行为型模式, 单例模式, 工厂模式, 观察者模式, 中介者模式, 访问者模式