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注解,关于该注解的笔记,参考:
这里有一个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
,相关笔记请参考:
如此一来,CoinType
枚举类对象就拥有了一个T get()
方法,即Coin get()
根据传入的CoinType
类型来返回不同的Coin
接口实现类的实例
现在代码我们已经完全可以看懂了,工厂模式的中心思想就是根据传入的参数来返回不同的实例
让用户更加专注于对象的使用,而不必关心对象的创建
而这其中,Coin
接口的关键作用就在于它充当了Supplier<T>
中的泛型T,因为两个实现类CopperCoin
和GoldCoin
都实现了Coin
类,这样才能使用T get()
方法返回不同的实例
而如果没有Coin
接口,那么就需要根据不同的实例类型来创建相同数量的方法,这也正是工厂模式的优点所在
当然,工厂模式并不一定非要接口,你也可以使用抽象类甚至实体类,只不过在真正的软件开发中,大都使用接口
以前也曾看过工厂模式的java代码,但是都远没有这个看起来那么的高级
他用到了枚举类型,函数式编程、注解等特性,可以说是非常优美的代码了