lambda设计模式_使用lambda的装饰器设计模式
lambda設(shè)計(jì)模式
隨著Java中l(wèi)ambda的出現(xiàn),我們現(xiàn)在有了一個(gè)新工具,可以更好地設(shè)計(jì)我們的代碼。 當(dāng)然,第一步是使用流,方法引用和Java 8中引入的其他簡(jiǎn)潔功能。
展望未來,我認(rèn)為下一步是重新訪問完善的設(shè)計(jì)模式,并通過功能性編程視角進(jìn)行了解。 為此,我將采用Decorator模式,并使用lambdas實(shí)現(xiàn)它。
我們將以裝飾器模式的簡(jiǎn)單且美味的示例為例:在披薩中添加澆頭。 這是GoF建議的標(biāo)準(zhǔn)實(shí)現(xiàn):
首先,我們具有定義組件的接口:
public interface Pizza {String bakePizza(); }我們有一個(gè)具體的組成部分:
public class BasicPizza implements Pizza {@Overridepublic String bakePizza() {return "Basic Pizza";} }我們決定必須以不同的方式裝飾組件。 我們選擇裝飾器模式。 這是抽象裝飾器:
public abstract class PizzaDecorator implements Pizza {private final Pizza pizza;protected PizzaDecorator(Pizza pizza) {this.pizza = pizza;}@Overridepublic String bakePizza() {return pizza.bakePizza();} }我們?yōu)榻M件提供一些具體的裝飾器:
public class ChickenTikkaPizza extends PizzaDecorator {protected ChickenTikkaPizza(Pizza pizza) {super(pizza);}@Overridepublic String bakePizza() {return super.bakePizza() + " with chicken topping";} }public class ProsciuttoPizza extends PizzaDecorator {protected ProsciuttoPizza(Pizza pizza) {super(pizza);}@Overridepublic String bakePizza() {return super.bakePizza() + " with prosciutto";} }這是使用新結(jié)構(gòu)的方式:
Pizza pizza = new ChickenTikkaPizza(new BasicPizza()); String finishedPizza = pizza.bakePizza(); //Basic Pizza with chicken toppingpizza = new ChickenTikkaPizza(new ProsciuttoPizza(new BasicPizza())); finishedPizza = pizza.bakePizza(); //Basic Pizza with prosciutto with chicken topping我們可以看到這會(huì)變得非?;靵y,如果考慮如何處理Java中的緩沖讀取器,它的確會(huì)變得非?;靵y:
new DataInputStream(new BufferedInputStream(new FileInputStream(new File("myfile.txt"))))當(dāng)然,您可以將其拆分為多行,但這不會(huì)解決混亂情況,只會(huì)分散它。 現(xiàn)在讓我們看看如何使用lambda來做同樣的事情。 我們從相同的基本組件對(duì)象開始:
public interface Pizza {String bakePizza(); }public class BasicPizza implements Pizza {@Overridepublic String bakePizza() {return "Basic Pizza";} }但是現(xiàn)在,我們不再聲明將提供裝飾模板的抽象類,而是創(chuàng)建裝飾器,該裝飾器向用戶詢問將裝飾組件的功能。
public class PizzaDecorator {private final Function<Pizza, Pizza> toppings;private PizzaDecorator(Function<Pizza, Pizza>... desiredToppings) {this.toppings = Stream.of(desiredToppings).reduce(Function.identity(), Function::andThen);}public static String bakePizza(Pizza pizza, Function<Pizza, Pizza>... desiredToppings) {return new PizzaDecorator(desiredToppings).bakePizza(pizza);}private String bakePizza(Pizza pizza) {return this.toppings.apply(pizza).bakePizza(); }}這條線構(gòu)成了要應(yīng)用的裝飾鏈:
Stream.of(desiredToppings).reduce(identity(), Function::andThen);這行代碼將獲取您的裝飾(屬于Function類型),并使用andThen鏈接它們。 這和
(currentToppings, nextTopping) -> currentToppings.andThen(nextTopping)并確保隨后按您提供的順序調(diào)用這些函數(shù)。 還將Function.identity()轉(zhuǎn)換為elem-> elem lambda表達(dá)式。 好吧,現(xiàn)在我們要在哪里定義裝飾? 您可以在PizzaDecorator甚至在界面中將它們添加為靜態(tài)方法:
public interface Pizza {String bakePizza();static Pizza withChickenTikka(Pizza pizza) {return new Pizza() {@Overridepublic String bakePizza() {return pizza.bakePizza() + " with chicken";}};}static Pizza withProsciutto(Pizza pizza) {return new Pizza() {@Overridepublic String bakePizza() {return pizza.bakePizza() + " with prosciutto";}};} }現(xiàn)在,這就是這種模式的使用方式:
String finishedPizza = PizzaDecorator.bakePizza(new BasicPizza(),Pizza::withChickenTikka, Pizza::withProsciutto);//And if you static import PizzaDecorator.bakePizza:String finishedPizza = bakePizza(new BasicPizza(),Pizza::withChickenTikka, Pizza::withProsciutto);如您所見,代碼變得更加清晰和簡(jiǎn)潔,我們沒有使用繼承來構(gòu)建裝飾器。
這只是可以使用lambda改進(jìn)的眾多設(shè)計(jì)模式之一。 還有更多功能可用來改善其余功能,例如使用部分應(yīng)用程序(循環(huán))來實(shí)現(xiàn)適配器模式。
希望我能引起您考慮對(duì)您的開發(fā)風(fēng)格采用功能更強(qiáng)大的編程方法的想法。
參考書目
裝飾器示例的靈感來自“ 四人幫” –“用裝飾器設(shè)計(jì)模式進(jìn)行裝飾”一文。
重構(gòu)方法是受以下Devoxx 2015演講的啟發(fā)(我建議在觀看這些演講時(shí)將其視為主題): Remi Forax重新加載的 設(shè)計(jì)模式,Venkat Subramaniam的Lambda表達(dá)式設(shè)計(jì)模式
翻譯自: https://www.javacodegeeks.com/2015/12/decorator-design-pattern-using-lambdas.html
lambda設(shè)計(jì)模式
總結(jié)
以上是生活随笔為你收集整理的lambda设计模式_使用lambda的装饰器设计模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微盟是做什么的 关于微盟简介
- 下一篇: 对象容器设计模式_容器对象模式。 一种新