Produce whole families of related objects through one interface, so they're always used together, never mismatched.
A UI toolkit with a light theme and a dark theme each needs a matching Button and Checkbox. If code picks a light Button but a dark Checkbox by accident, the screen looks broken. Factory Method solves "which class" for one product; it doesn't stop two related products from being created out of sync with each other.
An abstract factory interface declares a creation method per product (createButton, createCheckbox). Each concrete factory (LightFactory, DarkFactory) implements all of them, guaranteeing every product it hands out belongs to the same family.
`renderScreen` only knows the `UIFactory` interface — swapping `LightFactory` for `DarkFactory` changes every product at once, consistently.
const LightFactory = {
createButton: () => ({ render: () => "light button" }),
createCheckbox: () => ({ render: () => "light checkbox" }),
};
const DarkFactory = {
createButton: () => ({ render: () => "dark button" }),
createCheckbox: () => ({ render: () => "dark checkbox" }),
};
function renderScreen(factory) {
const button = factory.createButton();
const checkbox = factory.createCheckbox();
console.log(button.render(), "+", checkbox.render());
}
renderScreen(LightFactory); // light button + light checkbox
renderScreen(DarkFactory); // dark button + dark checkbox