简单工厂,工厂方法,抽象工厂

工厂模式实验报告

一.题目要求
本次上机实验需要我们掌握简单工厂模式、工厂方法模式、抽象工厂模式的设计方法,并进行设计应用,需要完成以下三个设计。
(1)简单工厂模式
使用简单工厂模式模拟女娲(Nvwa)造人(Person),如果传入参数M,则返回一个Man对象,如果传入参数W,则返回一个Woman对象,请实现该场景。现需要增加一个新的Robot类,如果传入参数R,则返回一个Robot对象,对代码进行修改并注意女娲的变化。
(2)工厂方法模式
海尔工厂(Haier)生产海尔空调(HaierAirCondition),美的工厂(Midea)生产美的空调(MideaAirCondition) 。使用工厂方法模式描述该场景,绘制类图并编程实现。
(3)抽象工程模式
电脑配件生产工厂生产内存、CPU等硬件设备,这些内存、CPU的品牌、型号并不一定相同,根据下面的“产品等级结构-产品族”示意图,使用抽象工厂模式实现电脑配件生产过程并绘制相应的类图,绘制类图并编程实现。

二.问题分析
2.1 题目分析
(1)简单工厂模式
①定义:
简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式是由一个工厂对象决定创建出哪一种产品类的实例,实质上是是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
②工厂角色:
工厂(Creator)角色:NvwaFactory类
抽象产品(Product)角色:Nvwa类
具体产品(Concrete Product)角色:Man类、Woman类、Robot类
③优缺点及使用场景:
优: 通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的.明确了各自的职责和权利,有利于整个软件体系结构的优化。
缺: 由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利;
使用场景: 工厂类负责创建的对象比较少;客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。

(2)工厂方法模式
①定义:
工厂方法模式(Factory Method Pattern)简称工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。
工厂方法模式完全实现‘开-闭 原则’,实现了可扩展。具有更复杂的层次结构,可以应用于产品结果复杂的场合。 工厂方法模式对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不再负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。
②工厂角色:
抽象工厂(Creator)角色:接口AirCondition
抽象产品(Product)角色:接口AirConditionFactory类
具体工厂(Concrete Creator)角色:HaierAirConditionFactory类和MideaAirConditionFactory类
具体产品(Concrete Product)角色::HaierAirCondition类和MideaAirCondition类
③优缺点及使用场景:
优: 工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节。能够让工厂自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。并且在系统中加入新产品时,完全符合开闭原则。
缺: 系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,会给系统带来一些额外的开销,增加了系统的抽象性和理解难度。
使用场景: 客户端不知道它所需要的对象的类(客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体产品对象由具体工厂类创建)。抽象工厂类通过其子类来指定创建哪个对象。

(3)抽象工厂模式
①定义:
抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据里氏替换原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。
产品族:
产品族是指位于不同产品等级结构中,功能相关联的产品组成的家族。一般是位于不同的等级结构中的相同位置上。对于每一个产品族,都有一个具体工厂。而每一个具体工厂创建属于同一个产品族,但是分属于不同等级结构的产品。
通过引进抽象工厂模式,可以处理具有相同(或者相似)等级结构的多个产品族中的产品对象的创建问题。
②工厂角色:
抽象工厂(AbstractFactory):接口Factory
具体工厂(ConcreteFactory):MacFactory类和PcFactory类
抽象产品(AbstractProduct):CPU接口和MAC接口
具体产品(ConcreteProduct):MacCPU类、MacRAM类和PcCPU类、 PcRAM类
③优缺点及使用场景:
优: 隔离了具体类的生成,使得客户端并不需要知道什么被创建
当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。增加新的产品族很方便,无须修改已有系统,符合开闭原则。
缺:增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了开闭原则。
使用场景:增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了开闭原则。

2.2 模块设计
(1)简单工厂模式
①设计Nvwa接口:

package SimpleFactory;
public interface Nvwa {
	public void play();
}

②设计Man类、Woman类及Robot类:
Man类:

package SimpleFactory;

public class Man implements Nvwa{
	public void play()
	{
		System.out.println("女娲成功造了一个男人");
	}	
}

Woman类:

package SimpleFactory;
public class Woman implements Nvwa{
		public void play()
		{
			System.out.println("女娲成功造了一个女人!");
		}	
}

Robot类:

package SimpleFactory;
	public class Robot implements Nvwa{
		public void play()
		{
			System.out.println("女娲成功造了一个机器人");
		}	
}

③设计工厂类NvwaFactory

package SimpleFactory;
public class NvwaFactory {
	public static Nvwa 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("对不起,暂不能创造该物种!");
			} 
		}
	}

④配置XML文件类XMLUtilNvwa:

package SimpleFactory;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import java.io.*;
public class XMLUtilNvwa
{
    //该方法用于从XML配置文件中提取品牌名称,并返回该品牌名称
	public static String getBrandName()
	{
		try
		{
			//创建文档对象
			DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = dFactory.newDocumentBuilder();
			Document doc;							
			doc = builder.parse(new File("SimpleFactoryconfigTV.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;
           	}
		}
}

⑤实现类Client:

package SimpleFactory;

public class Client {
	public static void main(String args[])
	{
		try { Nvwa nvwa;
		String brandName=XMLUtilNvwa.getBrandName(); 
		nvwa=NvwaFactory.producePerson(brandName);
		nvwa.play(); 
		} 
		catch(Exception e) 
		{ 
			System.out.println(e.getMessage());
			} 
		}
}

(2)工厂方法模式
①设计接口AirCondition:

package factorymethod;
public interface AirCondition {
	public void play();
}

②设计接口AirConditionFactory:

package factorymethod;
public interface AirConditionFactory {
	 public AirCondition produceAirCondition();
}

③设计HaierAirConditionFactory类

package factorymethod;
public class HaierConditionFactory  implements AirConditionFactory{
	public AirCondition produceAirCondition() 
	{ 
		System.out.println("海尔空调工厂生产海尔空调"); 
		return new HaierAirCondition(); 
		}
}

④MideaAirConditionFactory类

package factorymethod;
public class MideaAirConditionFactory implements AirConditionFactory{
	public AirCondition produceAirCondition() 
	{ 
		System.out.println("美的空调工厂生产美的空调"); 
		return new MideaAirCondition(); 
		}
}

⑤设计HaierAirCondition类

package factorymethod;
public class HaierAirCondition implements AirCondition {
	public void play()
	{
		System.out.println("海尔空调制造中......");
	}
}

⑥MideaAirCondition类

package factorymethod;
public class MideaAirCondition implements AirCondition {
	public void play()
	{
		System.out.println("美的空调制造中......");
	}

}

⑦配置XML文件类XMLUtil:

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;
	           	}
			}
	}

⑦设计实现类Client:

package factorymethod;
public class Client {
	public static void main(String args[])
	{ 
		try
		{
			AirCondition AirCondition;
			AirConditionFactory factory; 
			factory=(AirConditionFactory)XMLUtil.getBean(); 
			AirCondition=factory.produceAirCondition();
			AirCondition.play(); } catch(Exception e)
		{ 
				System.out.println(e.getMessage()); 
				}
		}
	

}

(3)抽象工厂模式
①设计接口CPU和RAM:

package abstractfactory;
public interface CPU {
	public void show();
}
package abstractfactory;
public interface RAM {
	public void play();
}

②设计接口Factory:

package abstractfactory;
public interface Factory {
	public RAM produceRAM();
	public CPU produceCPU();
}

③设计PcFactory类生产PcCPU和PcRAM:

package abstractfactory;
public class PcFactory implements Factory {
	public RAM produceRAM()
	{
		return new PcRAM();
	}
	public CPU produceCPU()
	{
		return new PcCPU();
	}
}

PcCPU类:

package abstractfactory;
public class PcCPU implements CPU{
	public void show()
	{
		System.out.println("PcCPU制造中......");
	}
}

PcRAM类:

package abstractfactory;
public class PcRAM implements RAM {
	public void play()
	{
		System.out.println("PcRAM制造中......");
	}
}

④设计MacFactory类生产MacCPU和MacRAM:
MacFactory类:

package abstractfactory;
public class MacFactory implements Factory{
public RAM produceRAM()
	{
		return new MacRAM();
	}
	public CPU produceCPU()
	{
		return new MacCPU();
	}
}

MacCPU类:

package abstractfactory;
public class MacCPU implements CPU{
public void show()
	{
		System.out.println("MacCPU制造中......");
	}
}

MacRAM类:

package abstractfactory;
public class MacRAM implements RAM{
	public void play()
	{
		System.out.println("MacRAM制造中......");
	}
}

⑤配置文件XMLUtil类:

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;
           	}
		}
}

⑥实现类Client:

package abstractfactory;
public class Client {
	public static void main(String args[]) 
	{ try 
	{ 
		Factory factory; 
		RAM ram;
		CPU cpu; 
		factory=(Factory)XMLUtil.getBean(); 
		ram=factory.produceRAM();
		ram.play(); 
		cpu=factory.produceCPU();
		cpu.show(); 
		}
	catch(Exception e) 
	{ 
		System.out.println(e.getMessage());
		}
	} 
}

三.UML类图
(1)简单工厂模式:
简单工厂,工厂方法,抽象工厂_第1张图片
(2)工厂方法模式:
简单工厂,工厂方法,抽象工厂_第2张图片
(3)抽象方法模式:
简单工厂,工厂方法,抽象工厂_第3张图片
四.调试及测试截图
(1)简单工厂模式:
①成功运行
在这里插入图片描述
②xml文件中传入W参数
简单工厂,工厂方法,抽象工厂_第4张图片
③xml文件中传入M参数
简单工厂,工厂方法,抽象工厂_第5张图片
④xml文件中传入R参数
简单工厂,工厂方法,抽象工厂_第6张图片
⑤传入参数错误则不能产生物种
简单工厂,工厂方法,抽象工厂_第7张图片
(2)工厂方法模式:
①成功运行
在这里插入图片描述
②生产Haier空调
简单工厂,工厂方法,抽象工厂_第8张图片
③生产Midea空调
简单工厂,工厂方法,抽象工厂_第9张图片
(3)抽象方法模式:
①Pc工厂生产产品
简单工厂,工厂方法,抽象工厂_第10张图片
②Mac工厂生产产品
简单工厂,工厂方法,抽象工厂_第11张图片
五.个人总结
(1)通过此次上机实验让我对简单工厂、工厂方法和抽象方法三种设计模式有了更加深入的了解,针对不同的场景模式选择不同的工厂方法,提高设计效率,增强程序的可维护性与易修改性。
(2)同时对xml文件有了简单的认识和了解,通过xml文件传入参数的不同来实现不同的运行结果。开始对于xml文件的读取不知道如何操作,最后在网上搜索资料并结合老师给出的源代码成功实现了xml文件的操作。在xml文件进行配置时,要注意类名是否一致,不一致将会出现错误。
(3)让我对Java接口以及实现类有了更加深入的认识。
(4)通过uml类图的绘制,能更加熟练地进行类图的绘制。

参考资料:https://blog.csdn.net/qq_38977097/article/details/81079268
https://blog.csdn.net/songhuanfei2017/article/details/89378574

你可能感兴趣的:(简单工厂,工厂方法,抽象工厂)