设计模式适配器模式_21世纪的设计模式:适配器模式
設計模式適配器模式
這是我的演講的第三部分,“ 21世紀的設計模式” 。
適配器模式橋接世界。 在一個世界中,我們有一個概念的界面。 在另一個世界,我們有不同的界面。 這兩個接口有不同的用途,但有時我們需要進行轉移。 在編寫良好的世界中,我們可以使用適配器使遵循一種協議的對象遵守另一種協議。
適配器模式有兩種。 我們不會談論這個:
interface Fire {<T> Burnt<T> burn(T thing); }interface Oven {Food cook(Food food); }class WoodFire implements Fire { ... }class MakeshiftOven extends WoodFire implements Oven {@Override public Food cook(Food food) {Burnt<Food> noms = burn(food);return noms.scrapeOffBurntBits();} }這種形式( 類Adapter模式)使我感到驚訝,因為extends給了我暴走的吉卜賽人。 為什么不在本文的討論范圍之內? 隨時問我,我會很樂意談論你的耳朵(可能是你的鼻子)。
取而代之的是讓我們談論對象適配器模式 ,該模式通常被認為在所有方面都更加有用和靈活。
讓我們看一下同一個類,遵循以下替代方法:
class MakeshiftOven implements Oven {private final Fire fire;public MakeshiftOven(Fire fire) {this.fire = fire;}@Override public Food cook(Food food) {Burnt<Food> noms = fire.burn(food);return noms.scrapeOffBurntBits();} }我們將像這樣使用它:
Oven oven = new MakeshiftOven(fire); Food bakedPie = oven.cook(pie);該模式通常遵循以下簡單結構:
很好,對嗎?
是。 有點。 我們可以做得更好。
我們已經有對Fire的引用,因此構造另一個僅用于Fire對象似乎有點…過大。 該對象實現了Oven 。 其中有一個抽象方法 。 我在這里看到一種趨勢。
相反,我們可以創建一個功能相同的函數。
Oven oven = food -> fire.burn(food).scrapeOffBurntBits(); Food bakedPie = oven.cook(pie);我們可以再進一步編寫方法引用,但是實際上情況變得更糟。
// Do *not* do this. Function<Food, Burnt<Food>> burn = fire::burn; Function<Food, Food> cook = burn.andThen(Burnt::scrapeOffBurntBits); Oven oven = cook::apply; Food bakedPie = oven.cook(pie);這是因為Java不能在功能接口之間進行隱式轉換,因此我們需要為它提供有關操作的每個階段的提示。 另一方面,Lambda對于任何具有正確類型的功能接口都是隱式強制的,并且編譯器在弄清楚如何做到這一點方面做得很好。
我們新的UML圖將如下所示:
通常,我們真正需要的只是方法參考。 例如,使用Executor界面。
package java.util.concurrent;/*** An object that executes submitted {@link Runnable} tasks.*/ public interface Executor {void execute(Runnable command); }它消耗了Runnable對象,這是一個非常有用的界面。
現在,我們將其中一個和一堆Runnable任務保存在Stream 。
Executor executor = ...; Stream<Runnable> tasks = ...;我們如何在執行Executor上執行所有這些Executor ?
這行不通:
tasks.forEach(executor);事實證明, Stream 上的forEach方法確實需要使用方,但是它是一個非常特定的類型:
public interface Stream<T> {...void forEach(Consumer<? super T> action);... }Consumer看起來像這樣:
@FunctionalInterface public interface Consumer<T> {void accept(T t);... }乍一看,這似乎沒有什么幫助。 但是請注意, Consumer是一個功能接口,因此我們可以使用lambda真正輕松地指定它們。 這意味著我們可以這樣做:
tasks.forEach(task -> executor.execute(task));對此可以進一步簡化:
tasks.forEach(executor::execute);Java 8使適配器變得非常簡單,以至于我猶豫不再將它們稱為模式。 這個概念仍然非常重要。 通過顯式創建適配器,我們可以將這兩個世界分開,除了在定義的邊界點處。 的實現,但是? 它們只是功能。
翻譯自: https://www.javacodegeeks.com/2015/04/design-patterns-in-the-21st-century-the-adapter-pattern.html
設計模式適配器模式
總結
以上是生活随笔為你收集整理的设计模式适配器模式_21世纪的设计模式:适配器模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ddos攻击怎么找攻击人(ddos攻击怎
- 下一篇: linux自动启动脚本(linux自动启