设计模式-工厂方法模式实例-01

设计模式-工厂方法模式实例-01

工厂方法模式/虚拟构造器模式/多态工厂模式(类创建型模式)

要点:

符合开闭原则。

优点:

向客户隐藏了那种具体产品将被实例化;

能让工厂自主确定创建何种产品对象;

加入新产品时符合开闭原则。

缺点:

类的个数成对增加,在一定程度上增加了系统复杂度,带来额外开销;

增加了系统抽象性和理解难度。

适用环境:

客户端不需要知道它所需要知道的对象的类;

抽象工厂通过其子类来指定创建哪个对象。

静态工厂模式与工厂方法模式的区别:

相同点:

两个工厂方法返回类型都是超类类型。

不同点:

中心不同。简单工厂模式工厂责任过重;

工厂方法不同。简单工厂模式为静态方法,工厂方法模式为动态;

简单工厂方法不支持开闭原则,工厂方法模式支持开闭原则;

工厂方法可扩展性好。

实例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>

 

 

测试成功!



 
 
posted @ 2022-03-02 19:52  临易  阅读(46)  评论(0编辑  收藏  举报