使用Java 8中的Lambda表達(dá)式實現(xiàn)工廠模式
前言
工廠模式是面向?qū)ο笤O(shè)計模式中大家最為熟知的設(shè)計模式之一。傳統(tǒng)的實現(xiàn)方式大家都在熟悉不過了,今天將向大家介紹使用Java8 Lambda 表達(dá)式更加優(yōu)雅的實現(xiàn)工廠模式。
封面
工廠模式在java中最常用的設(shè)計模式之一,它提供了一種很好的實例化對象的方法,是替代new操作的一種模式常用的方式。工廠設(shè)計模式可以讓你實例化對象的邏輯不用暴露給客戶端。
在下面的文章中我將給出使用傳統(tǒng)的代碼實現(xiàn)工廠模式的一個例子,然后再使用 Java8 Lambada 方式重新實現(xiàn)
一個例子
首先我將創(chuàng)建一個 Shape 接口以及幾個實現(xiàn)類,然后會在接下來的步驟中實現(xiàn)ShapeFactory,最后會給出詳細(xì)的調(diào)用實例并輸出結(jié)果。
新建接口:Shape.java
public interface Shape {
void draw();
}
定義兩個 Shape的實現(xiàn)類:Circle.java & Rectangle.java
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
創(chuàng)建Shape的工廠類,并實現(xiàn)根據(jù)指定參數(shù)返回不同的Shape的工廠方法:
public class ShapeFactory {
//use getShape method to get object of type shape
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
}
return null;
}
}
ShapeFactory 根據(jù)傳入的shapeType 返回不同的Shape。
下面是具體使用的例子。
public class FactoryPatternDemo {
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
//get an object of Circle and call its draw method.
Shape shape1 = shapeFactory.getShape("CIRCLE");
//call draw method of Circle
shape1.draw();
//get an object of Rectangle and call its draw method.
Shape shape2 = shapeFactory.getShape("RECTANGLE");
//call draw method of Rectangle
shape2.draw();
}
}
程序輸出
Inside Circle::draw() method. Inside Rectangle::draw() method.
使用Lambada實現(xiàn)工廠模式
Lambda表達(dá)式允許我們定義一個匿名方法,并允許我們以函數(shù)式接口的方式使用它。我們也希望能夠在已有的方法上實現(xiàn)同樣的特性。
方法引用和lambda表達(dá)式擁有相同的特性(例如,它們都需要一個目標(biāo)類型,并需要被轉(zhuǎn)化為函數(shù)式接口的實例),不過我們并不需要為方法引用提供方法體,我們可以直接通過方法名稱引用已有方法。
下面例子展示了構(gòu)造方法引用
Supplier circleSupplier = Circle::new; Circle circle = circleSupplier.get();
根據(jù)構(gòu)造方法引用的原理,我們可以重寫之前的代碼,定義一個Map來保存shape name 和它對應(yīng)的構(gòu)造方法引用:
final static Map<String, Supplier> map = new HashMap<>();
static {
map.put("CIRCLE", Circle::new);
map.put("RECTANGLE", Rectangle::new);
}
現(xiàn)在我們可以使用這個map來實例化不同的shapes
public class ShapeFactory {
final static Map<String, Supplier> map = new HashMap<>();
static {
map.put("CIRCLE", Circle::new);
map.put("RECTANGLE", Rectangle::new);
}
public Shape getShape(String shapeType){
Supplier shape = map.get(shapeType.toUpperCase());
if(shape != null) {
return shape.get();
}
throw new IllegalArgumentException("No such shape " + shapeType.toUpperCase());
}
}
使用lambada表達(dá)式實現(xiàn)的工廠方法來創(chuàng)建shape對象:
FactoryPatternDemo.java
public class FactoryPatternDemo {
public static void main(String[] args) {
Supplier shapeFactory = ShapeFactory::new;
//call draw method of circle
shapeFactory.get().getShape("circle").draw();
//call draw method of Rectangle
shapeFactory.get().getShape("rectangle").draw();
}
}
程序輸出
Inside Circle::draw() method. Inside Rectangle::draw() method.
這里的Shape::new可以被看作為lambda表達(dá)式的簡寫形式。盡管方法引用不一定(比如在這個例子里)會把語法變的更緊湊,但它擁有更明確的語義——如果我們想要調(diào)用的方法擁有一個名字,我們就可以通過它的名字直接調(diào)用它。
如果Shape構(gòu)造函數(shù)需要多個參數(shù),那么你就需要重新實現(xiàn)自己的Supplier
如:
() -> new Circe(args)
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
vue+springboot前后端分離工程跨域問題解決方案解析
這篇文章主要介紹了vue+springboot前后端分離工程跨域問題解決方案解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03
SpringMVC的@InitBinder參數(shù)轉(zhuǎn)換代碼實例
這篇文章主要介紹了SpringMVC的@InitBinder參數(shù)轉(zhuǎn)換代碼實例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-09-09
Java GZip 基于內(nèi)存實現(xiàn)壓縮和解壓的方法
這篇文章主要介紹了Java GZip 基于內(nèi)存實現(xiàn)壓縮和解壓的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08
阿里的Easyexcel讀取Excel文件的方法(最新版本)
這篇文章主要介紹了阿里的Easyexcel讀取Excel文件(最新版本)的方法,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-12-12
kafka并發(fā)寫大消息異常TimeoutException排查記錄
這篇文章主要為大家介紹了kafka并發(fā)寫大消息異常TimeoutException的排查記錄及解決方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02
Spring?Boot實現(xiàn)分布式任務(wù)調(diào)度的步驟
Spring?Boot提供了一些工具和框架,可以幫助我們輕松地實現(xiàn)分布式任務(wù)調(diào)度,在本文中我們將介紹如何使用Spring?Boot、Spring?Cloud、Quartz和Redis來實現(xiàn)分布式任務(wù)調(diào)度,感興趣的朋友跟隨小編一起看看吧2023-06-06
Spring Security如何使用URL地址進(jìn)行權(quán)限控制
這篇文章主要介紹了Spring Security如何使用URL地址進(jìn)行權(quán)限控制,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-12-12
PrintStream和PrintWriter的區(qū)別簡介
這篇文章主要介紹了PrintStream和PrintWriter的區(qū)別簡介,具有一定借鑒價值,需要的朋友可以參考下2018-01-01

