創(chuàng)建型模式(Creational Pattern)的主要特點(diǎn)是將對(duì)象的創(chuàng)建與使用分離,根據(jù)對(duì)象的創(chuàng)建與組合方式的不同,創(chuàng)建型模式可分為單例(Singleton)模式、原型(Prototype)模式、工廠方法(Factory Method)模式、抽象工廠(Abstract Factory)模式和建造者(Builder)模式 5 種。
本實(shí)驗(yàn)的主要目的如下。
⒈了解 5 種“創(chuàng)建型模式”的定義、特點(diǎn)和工作原理。
⒉理解 5 種“創(chuàng)建型模式”的結(jié)構(gòu)、實(shí)現(xiàn)和應(yīng)用場景。
⒊學(xué)會(huì)應(yīng)用 5 種“創(chuàng)建型模式”進(jìn)行軟件開發(fā)。
創(chuàng)建型模式隱藏了對(duì)象的創(chuàng)建細(xì)節(jié),對(duì)象的創(chuàng)建由相關(guān)的工廠來完成,使用者不需要關(guān)注對(duì)象的創(chuàng)建細(xì)節(jié),這樣可以降低系統(tǒng)的耦合度。創(chuàng)建型模式共 5 種,它們分別是單例模式、原型模式、工廠方法模式、抽象工廠模式和建造者模式,其工作原理在各自的教程中也都有詳細(xì)的介紹,每種模式的實(shí)驗(yàn)大概要花 2 個(gè)學(xué)時(shí),大家可以根據(jù)實(shí)驗(yàn)計(jì)劃來選做若干個(gè)實(shí)驗(yàn),下面以工廠方法模式為例,介紹其實(shí)驗(yàn)過程。
工廠方法模式(Factory Method Pattern),也叫虛擬構(gòu)造器(Virtual Constructor)模式或者多態(tài)工廠(Polymorphic Factory)模式。
在工廠方法模式中,工廠父類負(fù)責(zé)定義創(chuàng)建產(chǎn)品對(duì)象的公共接口,而工廠子類則負(fù)責(zé)生成具體的產(chǎn)品對(duì)象,這樣做的目的是將產(chǎn)品類的實(shí)例化操作延遲到工廠子類中完成。其結(jié)構(gòu)圖如圖 1 所示。
圖1 工廠方法模式的類圖
工廠方法模式包含如下角色。
? 抽象工廠(Abstract Factory):提供了創(chuàng)建產(chǎn)品的接口,調(diào)用者通過它訪問具體工廠的工廠方法 newProduct() 來創(chuàng)建產(chǎn)品。
? 具體工廠(ConcreteFactory):主要是實(shí)現(xiàn)抽象工廠中的抽象方法,完成具體產(chǎn)品的創(chuàng)建。
? 抽象產(chǎn)品(Product):定義了產(chǎn)品的規(guī)范,描述了產(chǎn)品的主要特性和功能。
? 具體產(chǎn)品(ConcreteProduct):實(shí)現(xiàn)了抽象產(chǎn)品角色所定義的接口,由具體工廠來創(chuàng)建,它同具體工廠之間一一對(duì)應(yīng)。
工廠方法模式的特點(diǎn)是當(dāng)系統(tǒng)擴(kuò)展需要添加新的產(chǎn)品對(duì)象時(shí),僅僅需要添加一個(gè)具體產(chǎn)品對(duì)象以及一個(gè)具體工廠對(duì)象,原有工廠對(duì)象不需要進(jìn)行任何修改,也不需要修改客戶端,很好地符合了“開閉原則”。
⒈ 用工廠方法模式設(shè)計(jì)一個(gè)電動(dòng)自行車工廠的模擬程序。
要求:要為每種品牌的電動(dòng)自行車提供一個(gè)子工廠,如愛瑪工廠專門負(fù)責(zé)生產(chǎn)愛瑪(Aima)牌電動(dòng)自行車,雅迪工廠專門負(fù)責(zé)生產(chǎn)雅迪(Yadea)牌電動(dòng)自行車。如果今后需要生產(chǎn)臺(tái)鈴(Tailg)牌電動(dòng)自行車,只需要增加一個(gè)新的臺(tái)鈴電動(dòng)自行車工廠即可,無須修改原有代碼,使得整個(gè)系統(tǒng)具有更強(qiáng)的靈活性和可擴(kuò)展性。(點(diǎn)此下載程序運(yùn)行后所要顯示的圖片)。
⒉按照以上要求設(shè)計(jì)類圖和編寫 Java 源程序。
所設(shè)計(jì)的實(shí)驗(yàn)程序要滿足以下兩點(diǎn)。
⒈體現(xiàn)“工廠方法模式”的工作原理。
⒉符合面向?qū)ο笾械?ldquo;開閉原則”。
⒈用 UML 設(shè)計(jì)“電動(dòng)自行車工廠模擬程序”的結(jié)構(gòu)圖。“電動(dòng)自行車工廠模擬程序”的結(jié)構(gòu)圖如圖 2 所示。
圖2 電動(dòng)自行車工廠模擬程序的結(jié)構(gòu)圖
⒉根據(jù)結(jié)構(gòu)圖寫出“電動(dòng)自行車工廠模擬程序”的源代碼。
① 電動(dòng)自行車工廠模擬程序的源代碼如下。
package FactoryMethod;
import java.awt.*;
import javax.swing.*;
public class BicycleFactoryTest
{
public static void main(String[] args)
{
try
{
Bicycle a;
BicycleFactory bf;
bf=(BicycleFactory) ReadXML.getObject();
a=bf.produce();
a.show();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
//抽象產(chǎn)品:自行車
interface Bicycle
{
public void show();
}
//具體產(chǎn)品:愛瑪自行車
class AimaBicycle implements Bicycle
{
JScrollPane sp;
JFrame jf=new JFrame("工廠方法模式測試");
public AimaBicycle()
{
JPanel p1=new JPanel();
p1.setLayout(new GridLayout(1,1));
p1.setBorder(BorderFactory.createTitledBorder("愛瑪自行車"));
JLabel l1=new JLabel(new ImageIcon("src/FactoryMethod/AIMABicycle.jpg"));
p1.add(l1);
sp=new JScrollPane(p1);
Container contentPane=jf.getContentPane();
contentPane.add(sp,BorderLayout.CENTER);
jf.pack();
jf.setVisible(false);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //用戶點(diǎn)擊窗口關(guān)閉
}
public void show()
{
jf.setVisible(true);
}
}
//具體產(chǎn)品:雅迪自行車
class YadeaBicycle implements Bicycle
{
JScrollPane sp;
JFrame jf=new JFrame("工廠方法模式測試");
public YadeaBicycle()
{
JPanel p1=new JPanel();
p1.setLayout(new GridLayout(1,1));
p1.setBorder(BorderFactory.createTitledBorder("雅迪自行車"));
JLabel l1=new JLabel(new ImageIcon("src/FactoryMethod/YadeaBicycle.jpg"));
p1.add(l1);
Container contentPane=jf.getContentPane();
sp=new JScrollPane(p1);
contentPane.add(sp, BorderLayout.CENTER);
jf.pack();
jf.setVisible(false);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //用戶點(diǎn)擊窗口關(guān)閉
}
public void show()
{
jf.setVisible(true);
}
}
//抽象工廠:自行車工廠
interface BicycleFactory
{
public Bicycle produce();
}
//具體工廠:愛瑪工廠
class AimaFactory implements BicycleFactory
{
public Bicycle produce()
{
System.out.println("愛瑪自行車生產(chǎn)了!");
return new AimaBicycle();
}
}
//具體工廠:雅迪工廠
class YadeaFactory implements BicycleFactory
{
public Bicycle produce()
{
System.out.println("雅迪自行車生產(chǎn)了!");
return new YadeaBicycle();
}
}
② 對(duì)象生成器的源代碼如下。
package FactoryMethod;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;
class ReadXML
{
public static Object getObject()
{
try
{
DocumentBuilderFactory dFactory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=dFactory.newDocumentBuilder();
Document doc;
doc=builder.parse(new File("src/FactoryMethod/config.xml"));
NodeList nl=doc.getElementsByTagName("className");
Node classNode=nl.item(0).getFirstChild();
String cName="FactoryMethod."+classNode.getNodeValue();
System.out.println("新類名:"+cName);
Class c=Class.forName(cName);
Object obj=c.newInstance();
return obj;
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
}
}
③XML 配置文件的代碼如下。
<?xml version="1.0" encoding="UTF-8"?>
<config>
<className>AimaFactory</className>
</config>
⒊上機(jī)測試程序,寫出運(yùn)行結(jié)果。
“電動(dòng)自行車工廠模擬程序”的運(yùn)行結(jié)果如圖 3 所示。
圖3 電動(dòng)自行車工廠模擬程序的運(yùn)行結(jié)果
⒋按同樣的步驟設(shè)計(jì)其他“創(chuàng)建型模式”的程序?qū)嵗?/p>
⒌寫出實(shí)驗(yàn)心得。