⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractfactory.htm

📁 程式设计是思维具体化的一种方式
💻 HTM
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>


  
  
  <link rel="stylesheet" href="css/stdlayout.css" type="text/css">


  
  
  <link rel="stylesheet" href="css/print.css" type="text/css">


  
  
  <meta content="text/html; charset=gb2312" http-equiv="content-type">


  
  
  <title>Abstract Factory 模式</title>
</head>


<body>


<h3><a href="http://caterpillar.onlyfun.net/GossipCN/index.html">From
Gossip@caterpillar</a></h3>


<h1><a href="CppGossip.html">Design Pattern: Abstract Factory 模式</a></h1>


假设您要制作一个对话方块(Dialog)元件,您希望的是这个对话方块可以有不同的视感(Look-and- feel),最基本的想法是,藉由Setter将不同视感的元件设定给这个对话方块,例如:<br>


<ul>
  <li> CustomDialog.java</li>
</ul>


<pre>public class CustomDialog {<br>    private IButton button;<br>    private ITextField textField;<br>    <br>    public void setButton(IButton button) {<br>        this.button = button;    <br>    }<br>    <br>    public void setTextField(ITextField textField) {<br>        this.textField = textField;<br>    }<br><br>    public void layoutAllComponents() {<br>        // ....<br>    }<br>    <br>    public void showDialog() {<br>        this.paintDialog();<br>        button.paintButton();<br>        textField.paintTextField();<br>    }<br>  <br>    public void paintDialog() {<br>        System.out.println("custom dialog paints....");<br>    }<br>}</pre>


<br>
很简单,这是最基本的介面依赖,Setter依赖于IButton与ITextField两个介面,而不是其实作类别,不过这边还有个进一步的要求,使用
上面的方式还必须亲自呼叫Setter、layout等方法,您希望视感的更换可以更简单些,例如只要透一个元件的替换就可以完成对话方块上所有元件的视
感更换。<br>
<br>
您可以使用Abstract Factory模式,将所有对话方块所需要的产生的元件加以封装,对话方块依赖于Abstract Factory,实际上具体的Factory实现则分别产生对话方块所需要的视感元件,下面的 UML 类别图展现这种概念。<br>
<div style="text-align: center;"><img style="width: 673px; height: 307px;" alt="AbstractFactory" title="AbstractFactory" src="images/abstractFactory-1.jpg"></div>
<br>
现在如果要更换所有的视感元件,就只要抽象掉具体的Factory就可以了,例如:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">CustomDialog windowsDialog = </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new CustomDialog(new WindowsWidgetFactory());</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">windowsDialog.showDialog();</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">CustomDialog macDialog = </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new CustomDialog(new MacWidgetFactory());</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">macDialog.showDialog();</span><br>
</div>
<br>
来将上面的UML图具体实现出来。<br>

<ul>
  <li> CustomDialog.java
  </li>
</ul>

<pre>public class CustomDialog {<br>    private IButton button;<br>    private ITextField textField;<br>    <br>    public CustomDialog(IWidgetFactory widgetFactory) {<br>        setWidgetFactory(widgetFactory);<br>    }<br>    <br>    // 由于客户端只依赖于抽象的工厂,工厂如何实作并无关客户端的事<br>    // 要抽换工厂并不需要改动客户端的程式<br>    public void setWidgetFactory(IWidgetFactory widgetFactory) {<br>        setButton(widgetFactory.getButton());<br>        setTextField(widgetFactory.getTextField());<br>     <br>    }<br><br>    public void layoutAllComponents() {<br>        // layout all components<br>    }<br>    <br>    // 这边也是依赖抽象,实际改变了元件实例<br>    // 客户端代码也不用更改<br>    public void setButton(IButton button) {<br>        this.button = button;    <br>    }<br>    <br>    public void setTextField(ITextField textField) {<br>        this.textField = textField;<br>    }<br>    <br>    public void showDialog() {<br>        this.paintDialog();<br>        button.paintButton();<br>        textField.paintTextField();<br>    }<br>  <br>    public void paintDialog() {<br>        System.out.println("custom dialog paints....");<br>    }<br>} <br></pre>

<br>

<ul>
  <li> IButton.java
  </li>
</ul>

<pre>public interface IButton {<br>    public void paintButton();<br>} <br></pre>

<br>

<ul>
  <li> ITextField.java
  </li>
</ul>

<pre>public interface ITextField {<br>    public void paintTextField();<br>} <br></pre>

<br>

<ul>
  <li> IWidgetFactory.java
  </li>
</ul>

<pre>public interface IWidgetFactory {<br>    public IButton getButton();<br>    public ITextField getTextField();<br>} <br></pre>

<br>

<ul>
  <li> MacButton.java
  </li>
</ul>

<pre>public class MacButton implements IButton {<br>    public void paintButton() {<br>        System.out.println("Mac button paints....");<br>    }<br>} <br></pre>

<br>

<ul>
  <li> WindowsButton.java
  </li>
</ul>

<pre>public class WindowsButton implements IButton {<br>    public void paintButton() {<br>        System.out.println("Windows button paints....");<br>    }<br>} <br></pre>

<br>

<ul>
  <li> MacTextField.java
  </li>
</ul>

<pre>public class MacTextField implements ITextField {<br>    public void paintTextField() {<br>        System.out.println("Mac textField paints....");<br>    }<br>} <br></pre>

<br>

<ul>
  <li> WindowsTextField.java
  </li>
</ul>

<pre>public class WindowsTextField implements ITextField {<br>    public void paintTextField() {<br>        System.out.println("Windows textField paints....");<br>    }<br>} <br></pre>

<br>

<ul>
  <li> MacWidgetFactory.java
  </li>
</ul>

<pre>public class MacWidgetFactory implements IWidgetFactory {<br>    public IButton getButton() {<br>        return new MacButton();<br>    }<br>    <br>    public ITextField getTextField() {<br>        return new MacTextField();<br>    }<br>} <br></pre>

<br>

<ul>
  <li> WindowsWidgetFactory.java
  </li>
</ul>

<pre>public class WindowsWidgetFactory <br>                          implements IWidgetFactory {<br>    public IButton getButton() {<br>        return new WindowsButton();<br>    }<br>    <br>    public ITextField getTextField() {<br>        return new WindowsTextField();<br>    }<br>}</pre>
<br>
下图是Abstract Factory模式的UML结构图:<br>
<div style="text-align: center;">
<div style="text-align: center;"><img style="width: 581px; height: 266px;" alt="AbstractFactory" title="AbstractFactory" src="images/abstractFactory-2.jpg"></div>
</div>
<br>
简单的说,在Abstract
Factory模式中将具体的Product封装在具体Factory实现中,而客户仍只要面对Factory与Product的抽象介面,避免依赖于具
体的Factory与Product,由于Factory封装了所必须的Product,所以要更换掉所有的元件,只要简单的抽换掉Factory就可以
了,不用修改客户端的程式。<br>
<br>


</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -