设计模式创建者模式抽象工厂AbstractFactory
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
[[《Design Patterns》]]
The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes.
wiki
关键字为:创建一组有关联的对象,不需要特别指定实体类
Client 为使用代码的角色
Factory 用于生产 XXXProduct
此时客户端编程将面向接口编程,而不是面向实现编程
动态性最差语言的 Java 的实现,这也是设计模式吹比高发区
package org.example;
import org.example.abstractfactory.*;
public class Main {
public static void main(String[] args) {
// 在这里修改需要切换的工厂
WidgetFactory wf = new PMWidgetFactory();
WidgetFactory wf2 = new MotifWidgetFactory();
// 使用了此对象创建方法后,之后的代码都不需要改了
// 问题的关键在于 Client 可能需要灵活使用不同的 Product 组
ScrollBar scrollBar = wf.CreateScrollBar();
Window window = wf.CreateWindow();
scrollBar.setColor("#FF00FF");
window.setBackgroundImage("./images/bg.jpg");
}
}
Python 的 OO 实现
from abc import ABC, abstractmethod
from sys import platform
# Products
class Button(ABC):
@abstractmethod
def paint(self):
pass
class LinuxButton(Button):
def paint(self):
return "Render a button in a Linux style"
class WindowsButton(Button):
def paint(self):
return "Render a button in a Windows style"
class MacOSButton(Button):
def paint(self):
return "Render a button in a MacOS style"
# Factory
class GUIFactory(ABC):
@abstractmethod
def create_button(self):
pass
class LinuxFactory(GUIFactory):
def create_button(self):
return LinuxButton()
class WindowsFactory(GUIFactory):
def create_button(self):
return WindowsButton()
class MacOSFactory(GUIFactory):
def create_button(self):
return MacOSButton()
# Client Invoke
if platform == "linux":
factory = LinuxFactory()
elif platform == "darwin":
factory = MacOSFactory()
elif platform == "win32":
factory = WindowsFactory()
else:
raise NotImplementedError(f"Not implemented for your platform: {platform}")
button = factory.create_button()
result = button.paint()
print(result)
PHP 的 OO 实现
<?php
// Products
interface Button {
public function paint();
}
class LinuxButton implements Button
{
public function paint() {
echo "Render a button in a Linux style";
}
}
class WindowsButton implements Button
{
public function paint() {
echo "Render a button in a Windows style";
}
}
class MacOSButton implements Button
{
public function paint() {
echo "Render a button in a MacOS style";
}
}
// Factory
interface GUIFactory {
public function createButton();
}
class LinuxFactory implements GUIFactory
{
public function createButton() {
return new LinuxButton();
}
}
class WindowsFactory implements GUIFactory
{
public function createButton() {
return new WindowsButton();
}
}
class MacOSFactory implements GUIFactory
{
public function createButton() {
return new MacOSButton();
}
}
# Client Invoke
$platform = 'linux';
if ($platform == "linux") {
$factory = new LinuxFactory();
} else if($platform == "darwin"){
$factory = new MacOSFactory();
} else if($platform == "win32"){
$factory = new WindowsFactory();
} else {
throw new Exception("Not implemented for your platform: {$platform}");
}
$button = $factory->createButton();
$result = $button->paint();
PHP 的高阶实现
<?php
// Products
class LinuxButton
{
public function paint() {
echo "Render a button in a Linux style";
}
}
class WindowsButton
{
public function paint() {
echo "Render a button in a Windows style";
}
}
class MacOSButton
{
public function paint() {
echo "Render a button in a MacOS style";
}
}
// Factory: I'm dead
# Client Invoke
// 如何利用动态性将 OO 的抽象工厂“干掉”,当类名可以作为参数进行传递并实例化的时候。
// 此时的 Button interface 仅仅作为一个约定而存在,因为动态语言本身不强制类型静态检查
// 我们可以将方法 paint 放到运行时检查,如此一来我们删减了大量的样板代码,程序更加清晰
// 至于需要面临的问题,留给读者自己思考与解决
// ===================================================
$platform = 'MacOS'; // Linux Windows MacOS
$className = "{$platform}Button";
$button = new $className();
// ===================================================
$result = $button->paint();