We know how to construct an assembly, but we don't know how to construct its components.
One of the biggest problems programmers of the 1990s faced was porting applications to new platforms. Often the majority of the code was the user interface, a complex tree-like structure of windows and controls. Unfortunately, these components were not exactly the same on Windows, Mac, and Linux. This meant that the GUI had to be recoded for each port.
Separate the construction of the assembly from the construction of its components by providing the assembly with abstract component classes for each type of component needed and an abstract factory that "makes" these components.
An abstract factory is a class (or interface) containing abstract factory methods for each type of abstract component.
A factory method is a normal method that creates and returns some type of object.
Assume some library provides concrete component classes extending each of the abstract component classes used by the assembly. Create a concrete factory implementing the abstract factory and pass it to the assembly constructor.

Of course the creators of the component library probably never heard of our abstract component classes. So even though the concrete components provide the desired functionality, they don't extend the desired abstract component classes. No problem, this is a job for the Adapter Pattern:

Here's an implementation of these diagrams:
Using this idea we could define abstract GUI component classes for windows, buttons, text fields, etc. We provide the GUI constructor with an abstract factory for making these components. On a Mac we create adapters that adapt the corresponding Mac GUI components to our abstract components and a concrete factor that makes these components.

e do the same for Windows, Linux, and any other GUI libraries we want. But notice: we never need to change the GUI constructor where all of the complex code that assembles the GUI resides!
In fact, this was the idea behind Java's Abstract Windows Toolkit (AWT). This enabled developers to create programs with complex GUIs that ran on any platform for which Java virtual machines (JVMs) existed.