Java 8 Lambda表達式實現工廠模式

摘要:

工廠模式是面向對象設計模式中你們最爲熟知的設計模式之一。傳統的實現方式你們都在熟悉不過了,今天將向你們介紹使用Java8 Lambda 表達式更加優雅的實現工廠模式。java

正文:

工廠模式在java中最經常使用的設計模式之一,它提供了一種很好的實例化對象的方法,是替代new操做的一種模式經常使用的方式。工廠設計模式可讓你實例化對象的邏輯不用暴露給客戶端。shell

在下面的文章中我將給出使用傳統的代碼實現工廠模式的一個例子,而後再使用 Java8 Lambada 方式從新實現express

一個例子

首先我將建立一個 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.");
   }
}

建立Shape的工廠類,並實現根據指定參數返回不一樣的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 根據傳入的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();
   }
}

程序輸出ide

Inside Circle::draw() method.
Inside Rectangle::draw() method.

使用Lambada實現工廠模式

Lambda表達式容許咱們定義一個匿名方法,並容許咱們以函數式接口的方式使用它。咱們也但願可以在已有的方法上實現一樣的特性。函數

方法引用和lambda表達式擁有相同的特性(例如,它們都須要一個目標類型,並須要被轉化爲函數式接口的實例),不過咱們並不須要爲方法引用提供方法體,咱們能夠直接經過方法名稱引用已有方法。下面例子展現了構造方法引用

Supplier<Shape> circleSupplier = Circle::new;
Circle circle = circleSupplier.get();

根據構造方法引用的原理,咱們能夠重寫以前的代碼,定義一個Map來保存shape name 和它對應的構造方法引用:

final static Map<String, Supplier<Shape>> map = new HashMap<>();
  static {
    map.put("CIRCLE", Circle::new);
    map.put("RECTANGLE", Rectangle::new);
  }

如今咱們可使用這個map來實例化不一樣的shapes

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());
  }
}

使用lambada表達式實現的工廠方法來建立shape對象:

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.

這裏的Shape::new能夠被看做爲lambda表達式的簡寫形式。儘管方法引用不必定(好比在這個例子裏)會把語法變的更緊湊,但它擁有更明確的語義——若是咱們想要調用的方法擁有一個名字,咱們就能夠經過它的名字直接調用它。

若是Shape構造函數須要多個參數,那麼你就須要從新實現本身的Supplier

如:

() -> new Circe(args)

做者信息
本文系力譜宿雲 LeapCloud技術團隊_數據服務組 成員:馬傳林【翻譯】
馬傳林,從事開發工做已經有多年。當前在MaxLeap數據服務組擔任開發工程師,主要負責MaxWon服務器開發。
原文:https://dzone.com/articles/fa...
譯文首發:https://blog.maxleap.cn/archi...

做者往期佳做
移動雲平臺的基礎架構之旅(一):雲應用
ORM 「殺器」之 JOOQ

相關閱讀
Java 8 Lambda限制:閉包

歡迎關注微信公衆號
圖片描述

相關文章
相關標籤/搜索