🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 多态工厂 《设计模式》这本书强调指出,采用“工厂方法”模式的原因是可以从基本工厂中继承出不同类型的工厂。 再次修改示例,使工厂方法位于单独的类中: ```java // patterns/ShapeFactory3.java // Polymorphic factory methods import java.util.*; import java.util.function.*; import java.util.stream.*; import patterns.shapes.*; interface PolymorphicFactory { Shape create(); } class RandomShapes implements Supplier<Shape> { private final PolymorphicFactory[] factories; private Random rand = new Random(42); RandomShapes(PolymorphicFactory... factories){ this.factories = factories; } public Shape get() { return factories[ rand.nextInt(factories.length)].create(); } } public class ShapeFactory3 { public static void main(String[] args) { RandomShapes rs = new RandomShapes( Circle::new, Square::new, Triangle::new); Stream.generate(rs) .limit(6) .peek(Shape::draw) .peek(Shape::erase) .count(); } } ``` 输出结果: ```java Triangle[0] draw Triangle[0] erase Circle[1] draw Circle[1] erase Circle[2] draw Circle[2] erase Triangle[3] draw Triangle[3] erase Circle[4] draw Circle[4] erase Square[5] draw Square[5] erase ``` **RandomShapes**实现了**Supplier \<Shape>**,因此可用于通过`Stream.generate()`创建**Stream**。 它的构造器采用**PolymorphicFactory**对象的可变参数列表。 变量参数列表以数组形式出现,因此列表是以数组形式在内部存储的。`get()`方法随机获取此数组中一个对象的索引,并在结果上调用`create()`以产生新的**Shape**对象。 添加新类型的**Shape**时,**RandomShapes**构造器是唯一需要更改的地方。 请注意,此构造器需要**Supplier \<Shape>**。 我们传递给其**Shape**构造器的方法引用,该引用可满足**Supplier \<Shape>**约定,因为Java 8支持结构一致性。 鉴于**ShapeFactory2.java**可能会抛出异常,使用此方法则没有任何异常——它在编译时完全确定。