Design Pattern: Abstract Factory 模式
假设您要制作一个对话方块(Dialog)元件,您希望的是这个对话方块可以有不同的视感(Look-and- feel),最基本的想法是,藉由Setter将不同视感的元件设定给这个对话方块,例如:
CustomDialog.java
public class CustomDialog { private IButton button; private ITextField textField; public void setButton(IButton button) { this.button = button; } public void setTextField(ITextField textField) { this.textField = textField; } public void layoutAllComponents() { // .... } public void showDialog() { this.paintDialog(); button.paintButton(); textField.paintTextField(); } public void paintDialog() { System.out.println("custom dialog paints...."); } }
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...."); } }
public interface IButton { public void paintButton(); }
public interface ITextField { public void paintTextField(); }
public interface IWidgetFactory { public IButton getButton(); public ITextField getTextField(); }
public class MacButton implements IButton { public void paintButton() { System.out.println("Mac button paints...."); } }
public class WindowsButton implements IButton { public void paintButton() { System.out.println("Windows button paints...."); } }
public class MacTextField implements ITextField { public void paintTextField() { System.out.println("Mac textField paints...."); } }
public class WindowsTextField implements ITextField { public void paintTextField() { System.out.println("Windows textField paints...."); } }
public class MacWidgetFactory implements IWidgetFactory { public IButton getButton() { return new MacButton(); } public ITextField getTextField() { return new MacTextField(); } }
public class WindowsWidgetFactory implements IWidgetFactory { public IButton getButton() { return new WindowsButton(); } public ITextField getTextField() { return new WindowsTextField(); } }