Абстрактная фабрика на Rust
Абстрактная фабрика — это порождающий паттерн проектирования, который решает проблему создания целых семейств связанных продуктов, без указания конкретных классов продуктов.
Абстрактная фабрика задаёт интерфейс создания всех доступных типов продуктов, а каждая конкретная реализация фабрики порождает продукты одной из вариаций. Клиентский код вызывает методы фабрики для получения продуктов, вместо самостоятельного создания с помощью оператора new
. При этом фабрика сама следит за тем, чтобы создать продукт нужной вариации.
GUI Elements Factory
This example illustrates how a GUI framework can organize its classes into independent libraries:
- The
gui
library defines interfaces for all the components.
It has no external dependencies. - The
windows-gui
library provides Windows implementation of the base GUI.
Depends ongui
. - The
macos-gui
library provides Mac OS implementation of the base GUI.
Depends ongui
.
The app
is a client application that can use several implementations of the GUI framework, depending on the current environment or configuration. However, most of the app
code doesn't depend on specific types of GUI elements. All the client code works with GUI elements through abstract interfaces (traits) defined by the gui
lib.
There are two approaches to implementing abstract factories in Rust:
- using generics (static dispatch)
- using dynamic allocation (dynamic dispatch)
When you're given a choice between static and dynamic dispatch, there is rarely a clear-cut correct answer. You'll want to use static dispatch in your libraries and dynamic dispatch in your binaries. In a library, you want to allow your users to decide what kind of dispatch is best for them since you don't know what their needs are. If you use dynamic dispatch, they're forced to do the same, whereas if you use static dispatch, they can choose whether to use dynamic dispatch or not.
gui: Abstract Factory and Abstract Products
gui/lib.rs
macos-gui: One family of products
macos-gui/lib.rs
windows-gui: Another family of products
windows-gui/lib.rs
Static dispatch
Here, the abstract factory is implemented via generics which lets the compiler create a code that does NOT require dynamic dispatch in runtime.
app: Client code with static dispatch
app/main.rs
app/render.rs
Dynamic dispatch
If a concrete type of abstract factory is not known at the compilation time, then is should be implemented using Box
pointers.