前言
工廠模式是面向對象設計模式中大家最為熟知的設計模式之一。傳統的實現方式大家都在熟悉不過了,今天將向大家介紹使用Java8 Lambda 表達式更加優雅的實現工廠模式。
封面
工廠模式在java中最常用的設計模式之一,它提供了一種很好的實例化對象的方法,是替代new操作的一種模式常用的方式。工廠設計模式可以讓你實例化對象的邏輯不用暴露給客戶端。
在下面的文章中我將給出使用傳統的代碼實現工廠模式的一個例子,然后再使用 Java8 Lambada 方式重新實現
一個例子
首先我將創建一個 Shape 接口以及幾個實現類,然后會在接下來的步驟中實現ShapeFactory,最后會給出詳細的調用實例并輸出結果。
新建接口:Shape.java
1
2
3
|
public interface Shape { void draw(); } |
定義兩個 Shape的實現類:Circle.java & Rectangle.java
1
2
3
4
5
6
7
8
9
10
11
12
|
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." ); } } |
創建Shape的工廠類,并實現根據指定參數返回不同的Shape的工廠方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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 根據傳入的shapeType 返回不同的Shape。
下面是具體使用的例子。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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(); } } |
程序輸出
1
2
|
Inside Circle::draw() method. Inside Rectangle::draw() method. |
使用Lambada實現工廠模式
Lambda表達式允許我們定義一個匿名方法,并允許我們以函數式接口的方式使用它。我們也希望能夠在已有的方法上實現同樣的特性。
方法引用和lambda表達式擁有相同的特性(例如,它們都需要一個目標類型,并需要被轉化為函數式接口的實例),不過我們并不需要為方法引用提供方法體,我們可以直接通過方法名稱引用已有方法。
下面例子展示了構造方法引用
1
2
|
Supplier circleSupplier = Circle:: new ; Circle circle = circleSupplier.get(); |
根據構造方法引用的原理,我們可以重寫之前的代碼,定義一個Map來保存shape name 和它對應的構造方法引用:
1
2
3
4
5
|
final static Map<String, Supplier> map = new HashMap<>(); static { map.put( "CIRCLE" , Circle:: new ); map.put( "RECTANGLE" , Rectangle:: new ); } |
現在我們可以使用這個map來實例化不同的shapes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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表達式實現的工廠方法來創建shape對象:
FactoryPatternDemo.java
1
2
3
4
5
6
7
8
9
|
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(); } } |
程序輸出
1
2
|
Inside Circle::draw() method. Inside Rectangle::draw() method. |
這里的Shape::new可以被看作為lambda表達式的簡寫形式。盡管方法引用不一定(比如在這個例子里)會把語法變的更緊湊,但它擁有更明確的語義——如果我們想要調用的方法擁有一個名字,我們就可以通過它的名字直接調用它。
如果Shape構造函數需要多個參數,那么你就需要重新實現自己的Supplier
如:
1
|
() -> new Circe(args) |
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。
原文鏈接:https://blog.maxleap.cn/archives/1300