Aja*_*gar 5 design-patterns functional-programming java-8
维基百科这里有一个装饰器模式的例子:
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());
}
Run Code Online (Sandbox Code Playgroud)
}
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";
}
};
}
Run Code Online (Sandbox Code Playgroud)
}
现在,我不太相信 CoffeeIngredientCalculator 中的解决方案。如果我们在 Coffee 接口中有一个单一的职责,getCost(),使用函数式风格和应用装饰器模式似乎更好更干净。它基本上可以归结为一个Function<Double,Double>,我们不需要抽象类,单独的装饰器,只需链接函数即可。
但是在咖啡示例中,在 Coffee 对象上有成本和描述的 2 个行为,我不太相信这是一个重要的增值,因为我们正在创建一个匿名类,覆盖 2 个方法。
问题:
1)这个解决方案可以接受吗?
2)如果没有,有没有更好的方法来使用函数式风格来解决它?
3)在我们装饰的对象有多个方法的情况下,我们是否应该坚持使用抽象类和单独的装饰器类的通常 GOF 方式?
所以,只是快速回答:
Coffee方法。取决于您的要求。由于Coffee不是函数式接口,即具有多个方法,因此您必须退回到普通的旧子类化。最后一点:如果您不喜欢匿名类,那么您可以编写private static内部类或其他类。一种更紧凑,另一种更适合垃圾收集器。
| 归档时间: |
|
| 查看次数: |
2771 次 |
| 最近记录: |