设计模式——工厂方法模式
使用Java实现了工厂方法模式,并且通过实例代码来了解工厂方法模式,证明了工厂方法模式符合“OCP”原则。
工厂方法模式
1.简单工厂模式的不足
在简单工厂模式中,只提供了一个工厂类,该工厂类处于对产品类进行实例化的中心位置,它知道每一个产品对象的创建细节,并决定何时实例化哪一个产品类。简单模式最大的缺点是当有新产品要加入到系统中时,必须要修改工厂类,加入必要的处理逻辑,这就违背了“开闭原则”。关于简单工厂模式可查看此链接:
2.工厂方法模式结构
2.1模式类图
工厂方法模式包含如下角色:
1.Product(抽象产品)
抽象产品是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的共同父类或接口。
2.ConcreteProduct(具体产品)
具体产品实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,它们之间一一对应,
3.Factory(抽象工厂)
在抽象工厂类中,声明了工厂方法(Factory Method),用于返回一个产品。抽象工厂是工厂方法模式的核心,它与应用程序无关。任何在模式中创建对象的工厂类都必须实现该接口。
4.ConcreteFactory(具体工厂)
具体工厂是抽象工厂类的子类,实现了抽象工厂中定义的工厂方法,并可由客户调用,返回一个具体产品类的实例。在具体工厂类中包含与应用程序密切相关发逻辑,并且既然等候应用程序调用以创建产品对象。
3.工厂方法模式实例与解析
题目:海尔工厂(Haier)生产海尔空调(HaierAirCondition),美的工厂(Midea)生产美的空调(MideaAirCondition) 。使用工厂方法模式描述该场景,绘制类图并编程实现。
3.1类图
3.2实例代码及解释
1.抽象产品类 Airconditioning(空调类)
public interface Airconditioning {
public void play();
}
Airconditioning作为抽象产品类,它可以是一个接口,也可以是一个抽象类,其中包含了所有产品都具有的业务方法play().
2.具体产品类HaierACD(海尔空调类)
public class HaierACD implements Airconditioning{
@Override
public void play() {
System.out.println("海尔空调使用中~");
}
}
HaierACD是抽象产品Airconditioning接口的子类,它是一种具体产品,实现了在Airconditioning接口中定义的业务方法paly()。
3.具体产品类MeideACD(美的空调类)
public class MeideACD implements Airconditioning{
@Override
public void play() {
System.out.println("美的空调使用中~");
}
}
MeideACD是抽象产品Airconditioning的另一个子类。
4.抽象工厂类AirconditioningFactory(空调工厂类)
public interface AirconditioningFactory {
public Airconditioning pruduceACD();
}
AirconditioningFactory是抽象工厂类,它可以是一个接口,也可以是一个抽象类,它包含了抽象的工厂方法Airconditioning pruduceACD(),返回一个抽象产品Airconditioning类型的对象。
5.具体工厂类HaierACDFactory(海尔空调工厂类)
public class HaierACDFactory implements AirconditioningFactory{
@Override
public Airconditioning pruduceACD() {
System.out.println("海尔空调已生产");
return new HaierACD();
}
}
HaierACDFactory是具体工厂类,它是一个抽象工厂类AirconditioningFactory的子类,实现了抽象工厂方法pruduceACD(),在工厂方法中创建并返回一个对象的具体产品。
6.具体工厂类MeideACDFactory(美的工厂类)
public class MeideACDFactory implements AirconditioningFactory{
@Override
public Airconditioning pruduceACD() {
System.out.println("美的空调已生产");
return new MeideACD();
}
}
3.3辅助代码
- XML操作工具类XMLUtil
package factor_method_pattern;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.*;
public class XMLUtil {
public static Object getBean(){
try {
//创建DOM文档对象
DocumentBuilderFactory dFactory =DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("config.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;
}
}
}
2.配置文件config.xml
<?xml version="1.0" ?>
<config >
<className>factor_method_pattern.MeideACDFactory</className>
</config>
3.客户端测试类Client
package factor_method_pattern;
public class Client {
public static void main(String[] args) {
try{
Airconditioning acd;
AirconditioningFactory acdfactory;
acdfactory = (AirconditioningFactory)XMLUtil.getBean();
acd = acdfactory.pruduceACD();
acd.play();
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
}
3.4结果及分析
如果在配置文件中将<className>节点中的内容设置为:MeideACDFactory,则会输出结果如下:
如果在配置文件中将<className>节点中的内容设置为:HaierACDFactory,则会输出结果如下:
如果需要增加一种新的类型的空调,如小天鹅空调,首先需要增加一个新的具体产品类XiaotianeACD,代码如下:
package factor_method_pattern;
public class XiaotianeACD implements Airconditioning{
@Override
public void play() {
System.out.println("小天鹅空调使用中~");
}
}
在对应增加一个具体工厂类XiaotianeACDFactory,代码如下:
package factor_method_pattern;
public class XiaotianeACDFactory implements AirconditioningFactory{
@Override
public Airconditioning pruduceACD() {
System.out.println("小天鹅空调已生产");
return new XiaotianeACD();
}
}
最后修改XML配置文件,修改后的代码如下:
<?xml version="1.0" ?>
<config >
<className>factor_method_pattern.XiaotianeACDFactory</className>
</config>
编译新增的两个类,运行客户端测试代码,结果如下:
4.工厂方法模式总结
4.1.工厂方法模式的优点
(1)在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪
种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
(2)基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够使工厂可
以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,是因为所有的具体工厂类都具有同一抽象父类。
(3)使用工厂方法模式的另一个优点是在系统中加人新产品时,无须修改抽象工厂和
抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。
4.2.工厂方法模式的缺点
(1)在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
(2) 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到 DOM、反射等技术,增加了系统的实现难度。
更多推荐
所有评论(0)