工厂方法模式/虚拟构造器模式/多态工厂模式(类创建型模式)
要点:
符合开闭原则。
优点:
向客户隐藏了那种具体产品将被实例化;
能让工厂自主确定创建何种产品对象;
加入新产品时符合开闭原则。
缺点:
类的个数成对增加,在一定程度上增加了系统复杂度,带来额外开销;
增加了系统抽象性和理解难度。
适用环境:
客户端不需要知道它所需要知道的对象的类;
抽象工厂通过其子类来指定创建哪个对象。
静态工厂模式与工厂方法模式的区别:
相同点:
两个工厂方法返回类型都是超类类型。
不同点:
中心不同。简单工厂模式工厂责任过重;
工厂方法不同。简单工厂模式为静态方法,工厂方法模式为动态;
简单工厂方法不支持开闭原则,工厂方法模式支持开闭原则;
工厂方法可扩展性好。
实例1:三种支付方式的实现。
类图
代码实现:
代码结构:
AbstractPay.java:
public abstract class AbstractPay {
public abstract void pay();
}
CashPay.java:
public class CashPay extends AbstractPay{
public void pay(){
System.out.println("cash pay!");
}
}
CreditcardPay.java:
public class CreditcardPay extends AbstractPay{
public void pay(){
System.out.println("Creditcard pay!");
}
}
PayMethodFactory.java:
import PayMethod.AbstractPay;
public abstract class PayMethodFactory {
public abstract AbstractPay getPayMethod();
}
CashPayFactory.java:
import PayMethod.AbstractPay;
import PayMethod.CashPay;
public class CashPayFactory extends PayMethodFactory{
public AbstractPay getPayMethod(){
return new CashPay();
}
}
CrediticardPayFactory.java:
import PayMethod.AbstractPay;
import PayMethod.CreditcardPay;
public class CrediticardPayFactory extends PayMethodFactory {
public AbstractPay getPayMethod(){
return new CreditcardPay();
}
}
XMLUtils.java:
import org.w3c.dom.*;
import javax.xml.parsers.*;
import org.xml.sax.SAXException;
import java.io.*;
public class XMLUtils {
public static Object getPayName(){
try {
//创建文档对象
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document;
document = documentBuilder.parse(new File("src/Utils/config.xml"));
//获取包含支付方式名称的文本节点
NodeList nodeList = document.getElementsByTagName("className");
Node classNode = nodeList.item(0).getFirstChild();
String payName = classNode.getNodeValue().trim();
//通过类名生成实例对象并将其返回
Class c = Class.forName(payName);
Object obj = c.newInstance();
return obj;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
config.xml:
<?xml version="1.0"?>
<config>
<className>Factory.CashPayFactory</className>
</config>
Client.java:
import Factory.PayMethodFactory;
import PayMethod.AbstractPay;
import Utils.XMLUtils;
public class Client {
public static void main(String[] args) {
try {
PayMethodFactory factory;
AbstractPay payMethod;
factory = (PayMethodFactory)XMLUtils.getPayName();
payMethod = factory.getPayMethod();
payMethod.pay();
}catch (Exception e){
System.out.println(e.getMessage());
}
}
}
测试启动项目:
此时,如果要添加一个支付方式,只需要增加一个具体类和一个具体工厂类。
例如:增加VoucherPay
VoucherPay.java:
public class VoucherPay extends AbstractPay{
public void pay(){
System.out.println("voucher pay!");
}
}
VoucherPayFactory.java:
import PayMethod.AbstractPay;
import PayMethod.VoucherPay;
public class VoucherPayFactory extends PayMethodFactory{
public AbstractPay getPayMethod(){
return new VoucherPay();
}
}
测试VoucherPay方式:
修改config.xml为:
<?xml version="1.0"?>
<config>
<className>Factory.VoucherPayFactory</className>
</config>
测试成功!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/128225.html