抽象工厂(Abstract Factory)设计模式

    首先,让我们考虑一个支持look-and-feel 标准的用户界面工具包,例如Motif 和 Presentation Manager。为了保证look and feel 的一致性,应用程序不应该为一个特定的look-and-feel 硬编码其窗口组件。因为这样将会造成以后很难改变窗口的观感。

    为了解决这一问题,我们定义了一个 WidgetFactory 类。这个类具有一些方法,用于创建不同的窗口组件。如 createScrollBar 方法将用于创建一个 ScrollBar,createWindow 方法将创建 Window 类。对WidgetFactory 的方法所能创建的每一类窗口组件,都对应一个抽象类。如这里的Window 和 ScrollBar。WidgetFactory 是一个抽象类,其子类将用于创建具体的窗口组件。如下图所示:

    从上面可以看出,当我们需要创建另一类 观感时,只需要继承 WidgetFactory 抽象工厂类,并覆盖其方法即可。

 

    这里使用的就是 Abstract Factory 抽象工厂模式。该模式的结构图如下所示:

 

    Abstract Factory 模式具有以下特点:

    1. 客户与具体实现分离。客户使用的是抽象产品。实现与使用分离。

    2. 易于扩展新的产品类。只需要实现一个新的实体工厂,并继承自抽象工厂,即可轻松获得一个新的产品类别。

    3. 产品一致性比较好。一个应用一次只能使用同一系列中的对象,如上面不能将 MotifWindow 和 PMScrollBar 混合起来使用。

    4. Abstract Factory 也有一个问题。即不容易扩展新种类的产品。针对这个问题,后面会有一个解决方法。

 

下面我们看一个抽象工厂类的例子。程序是用Java 写的。

 

首先是抽象工厂类

AbstractFactory.java:

public abstract class AbstractFactory {
        Button button;
        TextBox textbox;
        public abstract void createButton();
        public abstract void createTextbox();
}

可以看出,该类用于产生产品 Button 和 TextBox。Button 和 TextBox 也是抽象类。

Button.java:

public abstract class Button {
	protected abstract void createShape();
}

TextBox.java:

public abstract class TextBox {
	protected abstract void createText();
}


LinuxFactory 和 WindowsFactory 继承自 AbstractFactory。它们的createButton 分别产生 LinuxButton、LinuxTextBox 和 WindowsButton 、WindowsTextBox。

LinuxFactory.java:

public class LinuxFactory extends AbstractFactory {
	public void createButton() {
		button = new LinuxButton();
		button.createShape();
	}

	public void createTextbox() {
		textbox = new LinuxTextBox();
		textbox.createText();
	}
}

 

WindowsFactory.java:

public class WindowsFactory extends AbstractFactory {
	public void createButton() {
		button = new WindowsButton();
		button.createShape();
	}

	public void createTextbox() {
		textbox = new WindowsTextBox();
		textbox.createText();
	}
}

 

LinuxButton.java:

public class LinuxButton extends Button {
	protected void createShape() {
		System.out.println("create Linux Button");
	}
}

 

LinuxTextBox.java:

public class LinuxTextBox extends TextBox {
	protected void createText() {
		System.out.println("create linux textbox");
	}
}

 

WindowsButton.java:

public class WindowsButton extends Button {
	protected void createShape() {
		System.out.println("create windows button");
	}
}

 

WindowsTextBox.java:

public class WindowsTextBox extends TextBox {
	protected void createText() {
		System.out.println("create windows textbox");
	}
}


 

下面Client 类显示了抽象工厂模式中对象的使用:

Client.java:

public class Client {
	public static void main(String args[]) {
		AbstractFactory factory = new LinuxFactory();
		factory.createButton();
		factory.createTextbox();
		factory = new WindowsFactory();
		factory.createButton();
		factory.createTextbox();
	}
}


从Client 类可以看出,在使用抽象工厂模式时,用实体工厂创建创建工厂类,然后通过抽象工厂类创建部件。所创建的实体产品对客户透明。


 我们再来看这个设计。我们通过AbstractFactory 可以创建 Button 和 TextBox,但是现在我们需要创建另一种产品 TextField。这就比较难办了。我们需要更改Abstract Factory ,并更改所有继承了 AbstractFactory 的类。显然这样做是非常不合适的。因此 Abstract Factory 模式在扩展新产品时是有一些问题的。

一种解决办法是给创建对象的操作提供一个参数,这个参数用于指定被创建对象的种类。尽管这是一个可用的解决方案,但是也有一定问题。

因此,我们需要知道,扩展新产品不是Abstract Factory 模式的强项。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值