假设您要制作一个对话方块(Dialog)元件,您希望的是这个对话方块可以有不同的视感(Look-and- feel),最基本的想法是,藉由Setter将不同视感的元件设定给这个对话方块,例如:
- CustomDialog.java
public class CustomDialog { private IButton button; private ITextField textField; public CustomDialog(IWidgetFactory widgetFactory) { setWidgetFactory(widgetFactory); } // 由于客户端只依赖于抽象的工厂,工厂如何实作并无关客户端的事 // 要抽换工厂并不需要改动客户端的程式 public void setWidgetFactory(IWidgetFactory widgetFactory) { setButton(widgetFactory.getButton()); setTextField(widgetFactory.getTextField()); } public void layoutAllComponents() { // layout all components } // 这边也是依赖抽象,实际改变了元件实例 // 客户端代码也不用更改 public void setButton(IButton button) { this.button = button; } public void setTextField(ITextField textField) { this.textField = textField; } public void showDialog() { this.paintDialog(); button.paintButton(); textField.paintTextField(); } public void paintDialog() { System.out.println("custom dialog paints...."); }}
现在如果要更换所有的视感元件,就只要抽象掉具体的Factory就可以了,例如:
CustomDialog windowsDialog =
new CustomDialog(new WindowsWidgetFactory()); windowsDialog.showDialog(); CustomDialog macDialog = new CustomDialog(new MacWidgetFactory()); macDialog.showDialog();来将上面的UML图具体实现出来。
- CustomDialog.java
public class CustomDialog { private IButton button; private ITextField textField; public CustomDialog(IWidgetFactory widgetFactory) { setWidgetFactory(widgetFactory); } // 由于客户端只依赖于抽象的工厂,工厂如何实作并无关客户端的事 // 要抽换工厂并不需要改动客户端的程式 public void setWidgetFactory(IWidgetFactory widgetFactory) { setButton(widgetFactory.getButton()); setTextField(widgetFactory.getTextField()); } public void layoutAllComponents() { // layout all components } // 这边也是依赖抽象,实际改变了元件实例 // 客户端代码也不用更改 public void setButton(IButton button) { this.button = button; } public void setTextField(ITextField textField) { this.textField = textField; } public void showDialog() { this.paintDialog(); button.paintButton(); textField.paintTextField(); } public void paintDialog() { System.out.println("custom dialog paints...."); } }
- IButton.java
public interface IButton { public void paintButton(); }
- ITextField.java
public interface ITextField { public void paintTextField(); }
- IWidgetFactory.java
public interface IWidgetFactory { public IButton getButton(); public ITextField getTextField(); }
- MacButton.java
public class MacButton implements IButton { public void paintButton() { System.out.println("Mac button paints...."); } }
- WindowsButton.java
public class WindowsButton implements IButton { public void paintButton() { System.out.println("Windows button paints...."); } }
- MacTextField.java
public class MacTextField implements ITextField { public void paintTextField() { System.out.println("Mac textField paints...."); } }
- WindowsTextField.java
public class WindowsTextField implements ITextField { public void paintTextField() { System.out.println("Windows textField paints...."); } }
- MacWidgetFactory.java
public class MacWidgetFactory implements IWidgetFactory { public IButton getButton() { return new MacButton(); } public ITextField getTextField() { return new MacTextField(); } }
- WindowsWidgetFactory.java
public class WindowsWidgetFactory implements IWidgetFactory { public IButton getButton() { return new WindowsButton(); } public ITextField getTextField() { return new WindowsTextField(); } }下图是Abstract Factory模式的UML结构图:
简单的说,在Abstract Factory模式中将具体的Product封装在具体Factory实现中,而客户仍只要面对Factory与Product的抽象介面,避免依赖于具 体的Factory与Product,由于Factory封装了所必须的Product,所以要更换掉所有的元件,只要简单的抽换掉Factory就可以 了,不用修改客户端的程式。
==============================================================================
本文转自被遗忘的博客园博客,原文链接:http://www.cnblogs.com/rollenholt/archive/2012/04/23/2466958.html,如需转载请自行联系原作者