每个名副其实的Java程序员都知道Factory Pattern 。 这是一种便捷,标准化的方法,它通过教一个组件如何捕鱼而不是将它们交给它们来减少耦合。 但是,在使用大型系统时,该模式确实会向系统添加大量样板代码。 对于每个实体,您都需要许多不同的工厂来产生该实体的不同实现,这既麻烦又不需要编写。 这只是我们在Speedment中使用的许多新模式之一 。
这是一个典型的示例,您希望汽车商人能够在不知道确切实现的情况下创建Car
接口的实例。
汽车.java
public abstract class Car {
private final Color color;
public interface Factory {
Car make(Color color);
}
protected Car(Color color) {
this.color = color;
}
public abstract String getModel();
public abstract int getPrice();
}
沃尔沃
public final class Volvo extends Car {
public Volvo(Color color) {
super(color);
}
public String getModel() { return "Volvo"; }
public int getPrice() { return 10_000; } // USD
}
特斯拉
public final class Tesla extends Car {
public Tesla(Color color) {
super(color);
}
public String getModel() { return "Tesla"; }
public int getPrice() { return 86_000; } // USD
}
VolvoFactory.java
public final class VolvoFactory implements Car.Factory {
public Car make(Color color) { return new Volvo(color); }
}
TeslaFactory.java
public final class TeslaFactory implements Car.Factory {
public Car make(Color color) { return new Tesla(color); }
}
CarTrader.java
public final class CarTrader {
private Car.Factory factory;
private int cash;
public void setSupplier(Car.Factory factory) {
this.factory = factory;
}
public Car buyCar(Color color) {
final Car car = factory.make(color);
cash += car.getPrice();
return car;
}
}
Main.java
...
final CarTrader trader = new CarTrader();
trader.setSupplier(new VolvoFactory());
final Car a = trader.buyCar(Color.BLACK);
final Car b = trader.buyCar(Color.RED);
trader.setSupplier(new TeslaFactory());
final Car c = trader.buyCar(Color.WHITE);
...
您可能尚未注意到的一件事是,大多数这些组件在Java 8及更高版本中都是多余的。 由于工厂接口可能被视为@FunctionalInterface
我们不需要工厂,因此我们只需指定实现类的构造函数作为方法参考即可!
汽车.java
public abstract class Car {
private final Color color;
@FunctionalInterface
public interface Factory {
Car make(Color color);
}
}
Main.java
...
trader.setSupplier(Volvo::new);
trader.setSupplier(Tesla::new);
...
注意,实现类Volvo
和Tesla
不需要更改。 这两个工厂现在都可以拆除了,剩下的就是更为具体的系统!
(对于像这样的简单示例,根本不需要工厂接口。您也可以使CarTrader接受Function<Color
, Car>
。为工厂指定接口的优势在于,两者都更容易实现理解,它允许您更改构造函数的参数,而无需更改使用工厂的代码。)
翻译自: https://www.javacodegeeks.com/2016/02/make-factories-beautiful.html