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

Collette380 7年前發布 | 14K 次閱讀 工廠模式 Lambda Java8 Java開發

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

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

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

一個例子

首先我將創建一個 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 ShapegetShape(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) {
      ShapeFactoryshapeFactory = new ShapeFactory();
      //get an object of Circle and call its draw method.
      Shapeshape1 = shapeFactory.getShape("CIRCLE");
      //call draw method of Circle
      shape1.draw();
      //get an object of Rectangle and call its draw method.
      Shapeshape2 = shapeFactory.getShape("RECTANGLE");
      //call draw method of Rectangle
      shape2.draw();
  }
}

程序輸出

InsideCircle::draw() method.
InsideRectangle::draw() method.

使用Lambada實現工廠模式

Lambda表達式允許我們定義一個匿名方法,并允許我們以函數式接口的方式使用它。我們也希望能夠在已有的方法上實現同樣的特性。

方法引用和lambda表達式擁有相同的特性(例如,它們都需要一個目標類型,并需要被轉化為函數式接口的實例),不過我們并不需要為方法引用提供方法體,我們可以直接通過方法名稱引用已有方法。下面例子展示了構造方法引用

SuppliercircleSupplier = Circle::new;
Circlecircle = circleSupplier.get();

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

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

現在我們可以使用這個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 ShapegetShape(String shapeType){
    Suppliershape = 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) {
    SuppliershapeFactory =  ShapeFactory::new;
    //call draw method of circle
    shapeFactory.get().getShape("circle").draw();
    //call draw method of Rectangle
    shapeFactory.get().getShape("rectangle").draw();      
  }
}

程序輸出

InsideCircle::draw() method.
InsideRectangle::draw() method.

這里的Shape::new可以被看作為lambda表達式的簡寫形式。盡管方法引用不一定(比如在這個例子里)會把語法變的更緊湊,但它擁有更明確的語義——如果我們想要調用的方法擁有一個名字,我們就可以通過它的名字直接調用它。

如果Shape構造函數需要多個參數,那么你就需要重新實現自己的Supplier

如:

() -> new Circe(args)

 

 

來自:https://blog.maxleap.cn/archives/1300

 

 本文由用戶 Collette380 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!