返回
顶部

references:

https://github.com/iluwatar/java-design-patterns/tree/master/factory

根据github上的代码,CoinType这个枚举类的代码如下:

package com.iluwatar.factory;

import java.util.function.Supplier;
import lombok.Getter;

/**
 * Enumeration for different types of coins.
 */
@RequiredArgsConstructor
@Getter
public enum CoinType {

  COPPER(CopperCoin::new),
  GOLD(GoldCoin::new);

  private final Supplier<Coin> constructor;
}

可以看到他这里使用了一个RequiredArgsConstructor注解,关于该注解的笔记,参考:

RequiredArgsConstructor注解

这里有一个final修饰的字段constructor,如果我们手动进行该枚举类型的构造函数编写的话,代码应该如下:

package com.iluwatar.factory;

import java.util.function.Supplier;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

/**
 * Enumeration for different types of coins.
 */

@Getter
public enum CoinType {

  COPPER(CopperCoin::new),
  GOLD(GoldCoin::new);

  private final Supplier<Coin> constructor;
  CoinType(Supplier<Coin> constructor){
    this.constructor = constructor;
  }
}

上面的代码可以正常编译并运行

另外,Getter注解也可以删除,然后对代码作如下更改即可

package com.iluwatar.factory;

import java.util.function.Supplier;

/**
 * Enumeration for different types of coins.
 */

public enum CoinType {

  COPPER(CopperCoin::new),
  GOLD(GoldCoin::new);

  private final Supplier<Coin> constructor;
  CoinType(Supplier<Coin> constructor){
    this.constructor = constructor;
  }
  public Supplier<Coin> getConstructor() {
    return this.constructor;
  }
}

Getter注解就是为类自动生成getter方法

另外,还有一个令人疑惑的地方就是Supplier,相关笔记请参考:

Supplier接口

如此一来,CoinType枚举类对象就拥有了一个T get()方法,即Coin get()

根据传入的CoinType类型来返回不同的Coin接口实现类的实例

现在代码我们已经完全可以看懂了,工厂模式的中心思想就是根据传入的参数来返回不同的实例

让用户更加专注于对象的使用,而不必关心对象的创建

而这其中,Coin接口的关键作用就在于它充当了Supplier<T>中的泛型T,因为两个实现类CopperCoinGoldCoin都实现了Coin类,这样才能使用T get()方法返回不同的实例

而如果没有Coin接口,那么就需要根据不同的实例类型来创建相同数量的方法,这也正是工厂模式的优点所在

当然,工厂模式并不一定非要接口,你也可以使用抽象类甚至实体类,只不过在真正的软件开发中,大都使用接口

以前也曾看过工厂模式的java代码,但是都远没有这个看起来那么的高级

他用到了枚举类型,函数式编程、注解等特性,可以说是非常优美的代码了