po3a  

3、有一个饮料自动售货机(处理单价为5角钱)的控制处理软件,它的软件规格说明如下:

若投入5角钱的硬币,按下橙汁啤酒的按钮,则相应的饮料就送出来。若投入1元钱的硬币,同样也是按橙汁啤酒的按钮,则自动售货机在送出相应饮料的同时退回5角钱的硬币。

模拟程序如下:

 

因果图法测试该程序,并撰写实验报告。

实验步骤:

   ①编写程序

 

package org.example.test1;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;

public class VendingMachineGUI extends JFrame {
    // 组件声明
    private JLabel stateLabel = new JLabel("当前状态:");
    private JLabel balanceLabel = new JLabel("剩余零钱:5.0元");
    private JTextField coinField = new JTextField(10);
    private JButton orangeBtn = new JButton("橙汁");
    private JButton beerBtn = new JButton("啤酒");
    private JButton confirmBtn = new JButton("确定");
    private JButton resetBtn = new JButton("复位");
    private JTextArea outputArea = new JTextArea(5, 20);

    // 状态变量
    private double currentCoin = 0;
    private String selectedDrink = "";
    private double changeAvailable = 5.0; // 初始5元零钱(10个5角)
    private boolean canAcceptYuan = true;

    public VendingMachineGUI() {
        setTitle("自动售货机");
        setSize(400, 350);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        initComponents();
        updateStateDisplay();
    }

    private void initComponents() {
        // 布局设置
        JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
        JPanel inputPanel = new JPanel(new GridLayout(4, 2, 5, 5));

        // 状态显示
        inputPanel.add(new JLabel("机器状态:"));
        inputPanel.add(stateLabel);
        inputPanel.add(new JLabel("剩余零钱:"));
        inputPanel.add(balanceLabel);

        // 投币输入
        inputPanel.add(new JLabel("投入金额(0.5/1元):"));
        inputPanel.add(coinField);

        // 按钮面板
        JPanel btnPanel = new JPanel(new GridLayout(1, 2, 5, 5));
        btnPanel.add(orangeBtn);
        btnPanel.add(beerBtn);

        // 操作按钮
        JPanel controlPanel = new JPanel(new GridLayout(1, 2, 5, 5));
        controlPanel.add(confirmBtn);
        controlPanel.add(resetBtn);

        // 输出区域
        outputArea.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(outputArea);

        // 组装主界面
        mainPanel.add(inputPanel, BorderLayout.NORTH);
        mainPanel.add(btnPanel, BorderLayout.CENTER);
        mainPanel.add(controlPanel, BorderLayout.SOUTH);
        add(mainPanel, BorderLayout.NORTH);
        add(scrollPane, BorderLayout.CENTER);

        // 事件监听
        orangeBtn.addActionListener(e -> selectDrink("橙汁"));
        beerBtn.addActionListener(e -> selectDrink("啤酒"));

        confirmBtn.addActionListener(e -> processTransaction());
        resetBtn.addActionListener(e -> resetTransaction());

        coinField.addActionListener(e -> insertCoin());
    }

    private void updateStateDisplay() {
        balanceLabel.setText(String.format("剩余零钱:%.1f元", changeAvailable));
        stateLabel.setText(canAcceptYuan ? "【正常运营】" : "【零钱找完】");
        coinField.setEnabled(canAcceptYuan);
    }

    private void insertCoin() {
        try {
            double coin = Double.parseDouble(coinField.getText());
            if (coin == 0.5 || coin == 1.0) {
                currentCoin += coin;
                outputArea.append("已投入:" + coin + "元\n");
            } else {
                JOptionPane.showMessageDialog(this, "只接受0.5元或1元硬币");
            }
        } catch (NumberFormatException ex) {
            JOptionPane.showMessageDialog(this, "请输入有效数字");
        }
        coinField.setText("");
    }

    private void selectDrink(String drink) {
        selectedDrink = drink;
        outputArea.append("已选择:" + drink + "\n");
    }

    private void processTransaction() {
        if (currentCoin < 0.5) {
            JOptionPane.showMessageDialog(this, "请至少投入0.5元");
            return;
        }

        if (selectedDrink.isEmpty()) {
            JOptionPane.showMessageDialog(this, "请选择饮料");
            return;
        }

        double price = 0.5;
        double change = currentCoin - price;

        if (change < 0) {
            JOptionPane.showMessageDialog(this, "金额不足,还需投入" + (-change) + "元");
            return;
        }

        // 处理找零
        if (change > 0) {
            if (changeAvailable >= 0.5) {
                outputArea.append("找零:" + change + "元\n");
                changeAvailable -= change;
            } else {
                outputArea.append("零钱不足,退还:" + currentCoin + "元\n");
                resetTransaction();
                return;
            }
        }

        outputArea.append("已发放:" + selectedDrink + "\n");
        outputArea.append("交易完成!\n\n");

        // 更新状态
        if (changeAvailable < 0.5) {
            canAcceptYuan = false;
        }

        resetTransaction();
        updateStateDisplay();
    }

    private void resetTransaction() {
        currentCoin = 0;
        selectedDrink = "";
        coinField.setText("");
        updateStateDisplay();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            VendingMachineGUI vm = new VendingMachineGUI();
            vm.setVisible(true);
        });
    }
}

 

 ②分析原因与结果

原因:

C1:售货机有零钱找
C2:投入1元硬币
C3:投入5角硬币
C4:押下橙汁按钮
C5:押下啤酒按钮

 

结果:

E1:售货机”零钱找完”灯亮
E2:退还1元硬币
E3:退还5角硬币
E4:送出橙汁饮料
E5:送出啤酒饮料

 

中间结点:

11. 投入1元硬币且押下饮料按钮

12. 押下”橙汁”或”啤酒”的按钮

13. 应当找5角零钱并且售货机有零钱找

14. 钱已付清

 

 ③画出因果图

 

 

 ④转化为决策表

条件与中间节点

1

2

3

4

5

6

7

8

C1: 有零钱找

Y

Y

Y

N

Y

N

Y

N

C2: 投入1元

Y

Y

N

Y

N

Y

N

N

C3: 投入5角

N

N

Y

N

Y

N

N

N

C4: 按橙汁按钮

Y

N

Y

Y

N

N

N

N

C5: 按啤酒按钮

N

Y

N

N

Y

N

N

N

中间节点11

Y

Y

N

N

N

N

N

N

中间节点12

Y

Y

Y

Y

Y

Y

N

N

中间节点13

Y

N

Y

N

N

N

N

N

中间节点14

Y

Y

Y

N

N

N

N

N

结果

 

 

 

 

 

 

 

 

E1: 零钱找完灯亮

N

N

N

Y

N

Y

N

N

E2: 退还1元

N

N

N

Y

N

Y

N

N

E3: 退还5角

Y

N

Y

N

N

N

N

N

E4: 送出橙汁

Y

N

Y

N

N

N

N

N

E5: 送出啤酒

N

Y

N

N

Y

N

N

N

 

 

 ⑤根据决策表设计测试用例,得到测试用例表

用例编号

输入条件

预期结果

TC-01

C1=Y(有零钱),C2=Y(投入1元),C4=Y(按橙汁按钮)

E3=Y(退5角),E4=Y(送出橙汁)

TC-02

C1=Y(有零钱),C2=Y(投入1元),C5=Y(按啤酒按钮)

E5=Y(送出啤酒)

TC-03

C1=Y(有零钱),C3=Y(投入5角),C4=Y(按橙汁按钮)

E3=Y(退5角无效,需补投),E4=Y(送出橙汁)

TC-04

C1=N(无零钱),C2=Y(投入1元),C4=Y(按橙汁按钮)

E1=Y(零钱找完灯亮),E2=Y(退1元)

TC-05

C1=Y(有零钱),C3=Y(投入5角),C5=Y(按啤酒按钮)

E3=Y(退5角,因金额不足)

TC-06

C1=N(无零钱),C2=Y(投入1元),C5=Y(按啤酒按钮)

E1=Y(零钱找完灯亮),E2=Y(退1元)

TC-07

C1=Y(有零钱),C2=N(未投1元),C3=N(未投5角)

无操作(未投币)

TC-08

C1=N(无零钱),C2=N(未投1元),C3=N(未投5角)

无操作(未投币)

posted on 2025-03-27 09:21  po3a  阅读(92)  评论(0)    收藏  举报