?? abstractfactory.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;"> 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;"> </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;"> 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 + -