抽象工厂模式是一种创建型设计模式,它提供了一个接口用于创建相关或依赖对象的家族,而不需要指定具体类。该模式允许客户端在不知道具体类的情况下,通过其共同的接口来创建一组产品。
抽象工厂模式的概念
抽象工厂模式中包含多个工厂方法,每个工厂方法负责创建不同类型的对象。这种模式允许客户端在运行时创造所需的产品家族,而无需关心这些对象是如何创建和组合的。通常,一个工厂方法对应一个产品类别。
抽象工厂模式的优点
- 隔离具体类的生成:抽象工厂模式帮助隔离了具体类的生产。这使得客户端代码从具体类的创建中解耦。
- 易于交换产品系列:由于具体的工厂类在一个应用中仅需要在初始化的时候配置一次,这使得改变一个应用的产品族变得非常容易。
- 强调一致性:当一个产品族中的多个对象被设计成一起工作时,它能保证这一点。一个系统仅使用同一个产品族中的对象。
抽象工厂模式的缺点
- 难以支持新种类的产品:扩展抽象工厂以包括新的产品对象是困难的,因为抽象工厂接口确定了可以被创建的产品集合,支持新种类的产品需要扩展该工厂接口。
- 增加了系统的复杂性:由于引入了多个类和对象,系统的复杂性增加。
Java代码示例
考虑一个界面组件库的例子,我们有不同风格的UI组件如按钮、滚动条等。每个风格如Windows、Mac等将有不同的实现。
首先定义抽象产品和具体产品:
java复制代码
// 抽象产品
public interface Button {
void paint();
}
public interface ScrollBar {
void paint();
}
// 具体产品
public class WindowsButton implements Button {
@Override
public void paint() {
System.out.println("Render a button in a Windows style");
}
}
public class MacOSButton implements Button {
@Override
public void paint() {
System.out.println("Render a button in a MacOS style");
}
}
// 其他组件类似
然后定义抽象工厂和具体工厂:
java复制代码
// 抽象工厂
public interface GUIFactory {
Button createButton();
ScrollBar createScrollBar();
}
// 具体工厂
public class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public ScrollBar createScrollBar() {
// 返回Windows风格的ScrollBar
}
}
public class MacOSFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacOSButton();
}
@Override
public ScrollBar createScrollBar() {
// 返回MacOS风格的ScrollBar
}
}
使用抽象工厂:
java复制代码
public class Application {
private Button button;
private ScrollBar scrollBar;
private GUIFactory factory;
public Application(GUIFactory factory) {
this.factory = factory;
}
public void createUI() {
this.button = factory.createButton();
this.scrollBar = factory.createScrollBar();
}
public void paint() {
button.paint();
scrollBar.paint();
}
}
public class ApplicationRunner {
public static void main(String[] args) {
Application app = new Application(new WindowsFactory());
app.createUI();
app.paint();
}
}
在这个例子中,Application
类通过GUIFactory
抽象接口来创建UI组件,不直接与具体的产品类相互作用,增强了系统的灵活性和扩展性。