原文地址:https://dzone.com/articles/factory-pattern-using-lambda-expression-in-java-8?utm_source=Top%205&utm_medium=email&utm_campaign=2017-03-04
原廠模式是Java中最著名的模式之一。 如果你使用lambda運算式,你可以使用它們來實現模式,但要小心縮放。 通過 Monika Goel · 3月01日,17 · Java區
原廠模式是Java中最常用的設計模式之一。 這種類型的設計模式屬於主機的創造模式,因為這種模式提供了一種最好的方式來建立一個對象。 工廠設計模式允許您建立對象,而不將執行個體化邏輯暴露給用戶端。
在這篇文章中,我想給出一個Factory模式的樣本,然後使用在Java 8中引入的lambda運算式重寫相同的樣本。 原廠模式:一個例子
我將建立一個Shape介面以及實現Shape介面的具體類。 一個工廠類ShapeFactory被定義為下一步。
建立一個介面: Shape.java
public interface Shape { void draw();}
考慮這個Shape介面的兩個實現: 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."); }}
建立工廠根據給定資訊產生具體類的對象。
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; }}
使用Factory通過傳遞類型為: FactoryPatternDemo.java的資訊來擷取具體類的對象
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.
原廠模式:使用Lambda運算式的重構
在Java 8中,我們可以參考建構函式,就像我們引用方法一樣,通過使用
方法引用。 例如,下面是如何引用Circle建構函式:
Supplier<Shape> circleSupplier = Circle::new;Circle circle = circleSupplier.get();
使用這種技術,我們可以通過建立映射形狀的Map來重寫前面的代碼
名稱到其建構函式:
final static Map<String, Supplier<Shape>> map = new HashMap<>(); static { map.put("CIRCLE", Circle::new); map.put("RECTANGLE", Rectangle::new); }
我們現在可以使用這個Map來執行個體化不同的形狀,就像我們以前的工廠代碼一樣:
public class ShapeFactory { final static Map<String, Supplier<Shape>> map = new HashMap<>(); static { map.put("CIRCLE", Circle::new); map.put("RECTANGLE", Rectangle::new); } public Shape getShape(String shapeType){ Supplier<Shape> shape = map.get(shapeType.toUpperCase()); if(shape != null) { return shape.get(); } throw new IllegalArgumentException("No such shape " + shapeType.toUpperCase()); }}
使用工廠獲得具體類的對象,使用lambda運算式: FactoryPatternDemo.java
public class FactoryPatternDemo { public static void main(String[] args) { Supplier<ShapeFactory> 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.
這是一個相當整潔的方式使用Java 8功能來實現相同的意圖原廠模式。 但是這種技術不能很好地縮放,如果Factory 方法getShape 需要採取多個參數傳遞給Shape建構函式。 你必須提供與簡單的供應商不同的功能介面。