gpt4 book ai didi

design-patterns - 使用 Java 8 的装饰器模式

转载 作者:行者123 更新时间:2023-12-04 07:09:10 25 4
gpt4 key购买 nike

维基百科在这里有一个装饰器模式的例子:

https://en.wikipedia.org/wiki/Decorator_pattern#Second_example_.28coffee_making_scenario.29

我试图使用 Java 8 使用函数式风格来解决这个问题,我想出了解决方案:

1.CoffeeDecorator.java

public class CoffeeDecorator {

public static Coffee getCoffee(Coffee basicCoffee, Function<Coffee, Coffee>... coffeeIngredients) {

Function<Coffee, Coffee> chainOfFunctions = Stream.of(coffeeIngredients)
.reduce(Function.identity(),Function::andThen);
return chainOfFunctions.apply(basicCoffee);
}

public static void main(String args[]) {

Coffee simpleCoffee = new SimpleCoffee();
printInfo(simpleCoffee);

Coffee coffeeWithMilk = CoffeeDecorator.getCoffee(simpleCoffee, CoffeeIngredientCalculator::withMilk);
printInfo(coffeeWithMilk);

Coffee coffeeWithWSprinkle = CoffeeDecorator.getCoffee(coffeeWithMilk,CoffeeIngredientCalculator::withSprinkles);
printInfo(coffeeWithWSprinkle);

}

public static void printInfo(Coffee c) {
System.out.println("Cost: " + c.getCost() + "; Ingredients: " + c.getIngredients());
}

}

2.CoffeeIngredientCalculator.java
public class CoffeeIngredientCalculator {

public static Coffee withMilk(Coffee coffee) {
return new Coffee() {

@Override
public double getCost() {
return coffee.getCost() + 0.5;
}

@Override
public String getIngredients() {
return coffee.getIngredients() + " , Milk";
}
};
}

public static Coffee withSprinkles(Coffee coffee) {
return new Coffee() {

@Override
public double getCost() {
return coffee.getCost() + 0.2;
}

@Override
public String getIngredients() {
return coffee.getIngredients() + " , Sprinkles";
}
};
}

}

现在,我不太相信 CoffeeIngredientCalculator 中的解决方案。如果我们在 Coffee 接口(interface)中有一个单一的职责,getCost(),使用函数式样式并应用装饰器模式似乎会更好更简洁。它基本上可以归结为 Function<Double,Double> ,我们不需要抽象类,单独的装饰器,只需链接函数即可。

但是在咖啡的例子中,咖啡对象的成本和描述有两种行为,我不太相信这是一个重要的增值,因为我们正在创建一个匿名类,覆盖这两种方法。

问题:

1)这个解决方案可以接受吗?

2)如果没有,有没有更好的方法来使用功能样式来解决它?

3) 在我们正在装饰的对象有多个方法的情况下,我们是否应该坚持通常的 GOF 方式,即拥有一个抽象类和单独的装饰器类?

最佳答案

所以,只是快速回答:

  • 是的,可以接受
  • 虽然你可以装饰/配置 Coffee方法独立。取决于你的要求。由于Coffee不是功能接口(interface),即有多个方法,您必须退回到普通的旧子类化。
  • 不,您不必从字面上遵循 GoF。无论如何,他们描述了不止一种选择。

  • 最后一点:如果你不喜欢匿名类(class),那么你可以写 private static内部类,或其他。一个更紧凑,另一个更适合垃圾收集器。

    关于design-patterns - 使用 Java 8 的装饰器模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38629387/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com