首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Design Pattern: Abstract Factory 方式

2012-09-14 
Design Pattern: Abstract Factory 模式  假设您要制作一个对话方块(Dialog)元件,您希望的是这个对话方块

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....");        }    }

  很简单,这是最基本的介面依赖,Setter依赖于IButton与ITextField两个介面,而不是其实作类别,不过这边还有个进一步的要求,使用上面的方式还必须亲自呼叫Setter、layout等方法,您希望视感的更换可以更简单些,例如只要透一个元件的替换就可以完成对话方块上所有元件的视感更换。
  您可以使用Abstract Factory模式,将所有对话方块所需要的产生的元件加以封装,对话方块依赖于Abstract Factory,实际上具体的Factory实现则分别产生对话方块所需要的视感元件,下面的 UML 类别图展现这种概念。
abstractFactory-1.jpg



  现在如果要更换所有的视感元件,就只要抽象掉具体的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结构图:
abstractFactory-2.jpg



  简单的说,在Abstract Factory模式中将具体的Product封装在具体Factory实现中,而客户仍只要面对Factory与Product的抽象介面,避免依赖于具体的Factory与Product,由于Factory封装了所必须的Product,所以要更换掉所有的元件,只要简单的抽换掉Factory就可以了,不用修改客户端的程式。

我的小结:Abstract Factory抽象工厂模式的用法是把窗体的具体部件和窗体分离开了,中间加入了工厂类,通过不同的工厂类来实现不改变窗体代码的情况下修改窗体的显示,只需设置不同的工厂类对象即可。

热点排行