1、 题目分析
1.1题目内容
(1) 、简单工厂模式
使用简单工厂模式模拟女娲(Nvwa)造人(Person),如果传入参数M,则返回一个Man对象,如果传入参数W,则返回一个Woman对象,请实现该场景。现需要增加一个新的Robot类,如果传入参数R,则返回一个Robot对象,对代码进行修改并注意女娲的变化。
(2) 、工厂方法模式
海尔工厂(Haier)生产海尔空调(HaierAirCondition),美的工厂(Midea)生产美的空调(MideaAirCondition) 。使用工厂方法模式描述该场景,绘制类图并编程实现。
(3) 、抽象工程模式
电脑配件生产工厂生产内存、CPU等硬件设备,这些内存、CPU的品牌、型号并不一定相同,根据下面的“产品等级结构-产品族”示意图,使用抽象工厂模式实现电脑配件生产过程并绘制相应的类图,绘制类图并编程实现。
1.2题目分析
对于简单工厂模式,主要是实现工厂创造产品的功能,产品种类提前选定好,工厂可以实现选定好的产品的创造。要实现女娲造人的需求,要先写一个Person接口,再定义Man、Woman、Robot类来实现接口,Personfactory可以实现这三种类型的创造。
对于工厂方法模式,主要可以实现工厂创造产品功能,一个工厂只能创造一个品牌的一个产品。对于题目(2),海尔工厂只生成海尔空调,美的工厂只生产美的空调,首先创建工厂和空调接口,由海尔空调、美的空调实现空调接口,由海尔空调工厂、美的空调工厂实现工厂接口,再通过客户端传入参数,即可实现一个工厂生成一种产品的功能。
对于抽象工厂模式,主要用于实现一个工厂可以生产一种产品族,即一个工厂可以生产一个品牌的各个产品。对于题目(3),Pc工厂可以生产Pc系列产品,Mac工厂生产Mac系列产品,首先创建工厂类,Pc工厂和Mac工厂继承自工厂,再创建RAM类和CPU类,PcRAM和MacRAM继承自RAM类,PcCPU和MacCPU继承自CPU类,Pc的RAM和CPU依赖于Pc工厂,Mac的RAM和CPU依赖于Mac工厂,即可实现一个工厂生产一个产品族的需求。
2、 类图设计
简单工厂模式类图
工厂方法模式类图
抽象工厂模式类图
3、 源程序
简单工厂
package 简单工厂;
public interface Person {
public void play();
}
package 简单工厂;
public class Man implements Person{
public void play()
{
System.out.println("女娲创造男人......");
}
}
package 简单工厂;
public class Woman implements Person{
public void play()
{
System.out.println("女娲创造女人......");
}
}
package 简单工厂;
public class Robot implements Person{
public void play()
{
System.out.println("女娲创造机器人......");
}
}
package 简单工厂;
public class Personfactory {
public static Person producePerson(String brand) throws Exception
{
if(brand.equalsIgnoreCase("M"))
{
System.out.println("女娲创造男人!");
return new Man();
}
else if(brand.equalsIgnoreCase("W"))
{
System.out.println("女娲创造女人!");
return new Woman();
}
else if(brand.equalsIgnoreCase("R"))
{
System.out.println("女娲创造机器人!");
return new Robot();
}
else
{
throw new Exception("不能创造!");
}
}
}
package 简单工厂;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import java.io.*;
public class XMLUtilPerson
{
//该方法用于从XML配置文件中提取品牌名称,并返回该品牌名称
public static String getBrandName()
{
try
{
//创建文档对象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("SimpleFactoryconfigPerson.xml"));
//获取包含品牌名称的文本节点
NodeList nl = doc.getElementsByTagName("brandName");
Node classNode=nl.item(0).getFirstChild();
String brandName=classNode.getNodeValue().trim();
return brandName;
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
}
}
package 简单工厂;
public class Client {
public static void main(String args[])
{
try
{
Person p ;
String brandName=XMLUtilPerson.getBrandName();
p=Personfactory.producePerson(brandName);
p.play();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
工厂方法
package factorymethod;
public interface AirConditioner {
public void play();
}
package factorymethod;
public class HaierAirConditioner implements AirConditioner{
public void play()
{
System.out.println("海尔空调......");
}
}
package factorymethod;
public class MideaAirConditioner implements AirConditioner{
public void play()
{
System.out.println("美的空调......");
}
}
package factorymethod;
public interface AirConditionerFactory {
public AirConditioner produceAirConditioner();
}
package factorymethod;
public class HaierAirConditionerFactory implements AirConditionerFactory{
public AirConditioner produceAirConditioner()
{
System.out.println("海尔空调工厂生产海尔空调。");
return new HaierAirConditioner();
}
}
package factorymethod;
public class MideaAirConditionerFactory implements AirConditionerFactory{
public AirConditioner produceAirConditioner()
{
System.out.println("美的空调工厂生产美的空调。");
return new MideaAirConditioner();
}
}
package factorymethod;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import java.io.*;
public class XMLUtil
{
//该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象
public static Object getBean()
{
try
{
//创建文档对象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("FactoryMethodconfig.xml"));
//获取包含类名的文本节点
NodeList nl = doc.getElementsByTagName("className");
Node classNode=nl.item(0).getFirstChild();
String cName=classNode.getNodeValue();
//通过类名生成实例对象并将其返回
Class c=Class.forName(cName);
Object obj=c.newInstance();
return obj;
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
}
}
package factorymethod;
public class Client
{
public static void main(String args[])
{
try
{
AirConditioner a;
AirConditionerFactory factory;
factory=(AirConditionerFactory)XMLUtil.getBean();
a=factory.produceAirConditioner();
a.play();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
抽象工厂
package abstractfactory;
public interface EFactory {
public RAM produceRAM();
public CPU produceCPU();
}
package abstractfactory;
public class PcFactory implements EFactory
{
public RAM produceRAM()
{
return new PcRAM();
}
public CPU produceCPU()
{
return new PcCPU();
}
}
package abstractfactory;
public class MacFactory implements EFactory
{
public RAM produceRAM()
{
return new MacRAM();
}
public CPU produceCPU()
{
return new MacCPU();
}
}
package abstractfactory;
public interface CPU {
public void play();
}
package abstractfactory;
public class MacCPU implements CPU{
public void play()
{
System.out.println("MacCPU生产中......");
}
}
package abstractfactory;
public class PcCPU implements CPU{
public void play()
{
System.out.println("PcCPU生产中......");
}
}
package abstractfactory;
public interface RAM {
public void play();
}
package abstractfactory;
public class MacRAM implements RAM{
public void play()
{
System.out.println("MacRAM生产中......");
}
}
package abstractfactory;
public class PcRAM implements RAM{
public void play()
{
System.out.println("PcRAM生产中......");
}
}
package abstractfactory;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import java.io.*;
public class XMLUtil
{
//该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象
public static Object getBean()
{
try
{
//创建文档对象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("AbstractFactoryconfig.xml"));
//获取包含类名的文本节点
NodeList nl = doc.getElementsByTagName("className");
Node classNode=nl.item(0).getFirstChild();
String cName=classNode.getNodeValue();
//通过类名生成实例对象并将其返回
Class c=Class.forName(cName);
Object obj=c.newInstance();
return obj;
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
}
}
package abstractfactory;
public class Client
{
public static void main(String args[])
{
try
{
EFactory factory;
RAM r;
CPU c;
factory=(EFactory)XMLUtil.getBean();
r=factory.produceRAM();
r.play();
c=factory.produceCPU();
c.play();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
4、 程序测试及调试结果
程序调试结果
程序测试结果
图(1)、图(2)的运行结果有错误,图(1)的错误是找不到指定的文件,经过查询发现出现错误是因为XML文件中的文件名称与自己定义的文件名称不一致导致的,图(2)的问题是由于不细心在记事本中写入不符合要求的参数而导致的错误。图(3)、图(4)是简单工厂模式问题的运行结果;图(5)、图(6)是工厂方法模式问题的运行结果;图(7)、图(8)是抽象工厂模式问题的运行结果。
5、 经验总结
通过本次上机,我对面向对象程序设计有了更深的理解以及应用,也学习了三种设计模式,分别是简单工厂模式,工厂方法模式,抽象工厂模式。对于简单工厂模式,主要是实现工厂创造产品的功能,产品种类提前选定好,工厂可以实现选定好的产品的创造。对于工厂方法模式,主要可以实现工厂创造产品功能,一个工厂只能创造一个品牌的一个产品。对于抽象工厂模式,主要用于实现一个工厂可以生产一种产品族,即一个工厂可以生产一个品牌的各个产品。这三种设计模式各自有各自的优缺点和适用类型,通过学习设计模式,我发现设计模式很重要,在解决实际问题上给我们带来了很多方便之处。在本次上机中,我出现的问题都是由于不细心检查不当造成的,以后我会改掉这个缺点。以上就是我对此次上机的总结和体会。