
Вот типичный пример, когда вы хотите, чтобы автомобильный трейдер мог создавать экземпляры интерфейса Car не зная точной реализации.
Car.java
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
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();} |
Volvo.java
|
1
2
3
4
5
6
7
8
|
public final class Volvo extends Car { public Volvo(Color color) { super(color); } public String getModel() { return "Volvo"; } public int getPrice() { return 10_000; } // USD} |
Tesla.java
|
1
2
3
4
5
6
7
8
|
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
|
1
2
3
|
public final class VolvoFactory implements Car.Factory { public Car make(Color color) { return new Volvo(color); }} |
TeslaFactory.java
|
1
2
3
|
public final class TeslaFactory implements Car.Factory { public Car make(Color color) { return new Tesla(color); }} |
CarTrader.java
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
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
|
1
2
3
4
5
6
7
8
|
... 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 нам не нужны фабрики, мы можем просто указать конструктор реализующих классов в качестве ссылки на метод!
Car.java
|
1
2
3
4
5
6
7
8
|
public abstract class Car { private final Color color; @FunctionalInterface public interface Factory { Car make(Color color); }} |
Main.java
|
1
2
3
4
|
... trader.setSupplier(Volvo::new); trader.setSupplier(Tesla::new); ... |
Обратите внимание, что не требуется никаких изменений для классов реализации Volvo и Tesla . Обе фабрики теперь можно убрать, и у вас останется гораздо более конкретная система!
(Для простых примеров, таких как этот, Factory-интерфейс вообще не нужен. Вы также можете заставить CarTrader использовать Function<Color , Car> . Преимущество указания интерфейса для фабрики состоит в том, что и то, и другое проще понять, и это позволяет изменить параметры конструктора без изменения кода, который использует фабрику.)
| Ссылка: | Сделайте ваши фабрики красивыми от нашего партнера JCG Эмиля Форслунда из блога Age of Java . |