使用Lambdas重構工廠設計模式
工廠設計模式讓我們建立物件而不將例項化邏輯暴露給客戶端。例如,假設您正在為銀行工作,他們需要一種建立不同金融產品的方式:貸款,債券,股票等。讓我們繪製一個類圖並編寫一些程式碼來理解Factory Design Pattern,然後使用lambda表示式來刪除樣板程式碼。
工廠設計模式:不使用Lambda表示式
通常我們使用一個負責建立不同物件的方法建立一個Factory類,如下所示:
<b>public</b> <b>class</b> FactoryMain { <b>public</b> <b>static</b> <b>void</b> main(String[] args) { Product p1 = ProductFactory.createProduct(<font>"loan"</font><font>); } } <b>public</b> <b>class</b> ProductFactory { <b>public</b> <b>static</b> Product createProduct(String name){ <b>switch</b>(name){ <b>case</b> </font><font>"loan"</font><font>: <b>return</b> <b>new</b> Loan(); <b>case</b> </font><font>"stock"</font><font>: <b>return</b> <b>new</b> Stock(); <b>case</b> </font><font>"bond"</font><font>: <b>return</b> <b>new</b> Bond(); <b>default</b>: <b>throw</b> <b>new</b> RuntimeException(</font><font>"No such product "</font><font> + name); } } } <b>static</b> <b>private</b> <b>interface</b> Product {} <b>static</b> <b>private</b> <b>class</b> Loan implements Product {} <b>static</b> <b>private</b> <b>class</b> Stock implements Product {} <b>static</b> <b>private</b> <b>class</b> Bond implements Product {} } </font>
在這裡,貸款,股票和債券 都是產品的 子型別。所述createProduct() 方法可以有額外的邏輯來配置每個建立的產品。但好處是您現在可以建立這些物件,而無需將建構函式和配置暴露給客戶端,這使得客戶端的產品建立更簡單:
Product p = ProductFactory.createProduct("loan");
工廠設計模式:使用Lambda表示式
我們可以通過使用方法引用來引用建構函式,就像引用方法一樣。例如,以下是如何引用Loan建構函式:
Supplier<Product> loanSupplier = Loan::<b>new</b>; Loan loan = loanSupplier.get();
使用此技術,您可以通過建立將產品名稱對映到其建構函式的Map來重寫以前的程式碼:
<b>private</b> <b>final</b> <b>static</b> Map<String, Supplier<Product>> map = <b>new</b> HashMap<>(); <b>static</b> { map.put(<font>"loan"</font><font>, Loan::<b>new</b>); map.put(</font><font>"stock"</font><font>, Stock::<b>new</b>); map.put(</font><font>"bond"</font><font>, Bond::<b>new</b>); } </font>
讓我們使用這個Map來例項化不同的產品,就像你使用工廠設計模式一樣:
<b>public</b> <b>static</b> Product createProductLambda(String name){ Supplier<Product> p = map.get(name); <b>if</b>(p != <b>null</b>) <b>return</b> p.get(); <b>throw</b> <b>new</b> RuntimeException(<font>"No such product "</font><font> + name); } </font>