美文网首页
客观题型自动阅卷系统(管道过滤器模式)

客观题型自动阅卷系统(管道过滤器模式)

作者: Ramsey16k | 来源:发表于2019-10-28 21:18 被阅读0次

这周,我的软件设计体系结构老师留了这么道题

客观题型自动阅卷系统体系结构分析:
1、 分析基本的系统需求;
2、 针对系统需求,试用“管道-过滤器”风格进行架构设计:
a) 画出系统架构图。
b) 描述架构图中各组件(过滤器)、管道、数据源、数据池等功能。
c) 选用一种程序设计语言实现这一系统,并分析其可行性、合理性。

这道题乍一听很抽象,我写好程序以后感觉收货颇多,对管道-过滤器模式理解很深刻。所以写篇博客记录一下。(emmm架构图我就不放了哈哈)

1.基本的系统需求

(1)客观题的切割
将试卷按照区域或题目进行图片切分,将切割后的图片递交给评分模块。

(2) 扫描试卷
通过扫描仪对答题卡进行扫描,将试卷答案录入到系统里。

(3)客观题自动评分
录入客观题标准的答案,然后评分模块通过对比当前试卷的答案和标准答案来判断对错。

(4)分数累加计算
所有客观题评判完毕,自动计算总分数。

2. 描述架构图中各组件(过滤器)、管道、数据源、数据池等功能。

数据源:试卷,提供系统的初始数据流

管道:扫描仪,经过扫描仪的扫描以后,答题卡变成了按顺序排列的选项字母

过滤器:判卷服务器,即判断对错的程序,经过程序对比考生的选项和标准答案,计算各题得出考生的客观题各个题的得分。

数据池:考生的客观题作答情况输出到数据池,数据池计算得出总成绩,即程序的最终结果,将结果显示给阅卷老师。

3.Java代码实现(模拟管道过滤器模式)

这是我的思路:
(1)通过扫描仪扫描客观题的答案,然后写入管道。
(2)通过管道进入过滤器,分别对每道题进行评分,然后写入下一个管道。
(3)过滤后的每道题,通过管道到达数据池,在数据池取出每道题的得分,汇总计算出总成绩。

具体实现代码如下:
  • Packet(试题类)
package filter;

public class Packet {
    private int pno = -1;
    private String content;
    private int score = 0;

    public Packet() {
    }

    public Packet(int pno) {
        this.pno = pno;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getContent() {
        return content;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    public int getPno() {
        return pno;
    }

    @Override
    public String toString() {
        return "试题{" +
                "题号:" + pno +
                ", 选项:'" + content + '\'' +
                '}';
    }
}

  • Filter(过滤器)
package filter;

public abstract class Filter {
    protected Pipe input;
    protected Pipe output;

    public Filter(Pipe input, Pipe output) {
        this.input = input;
        this.output = output;
    }

    public abstract void process();
}

  • FilterImpl(过滤器的实现)
package filter;

public class FilterImpl extends Filter {

    public FilterImpl(Pipe input, Pipe output) {
        super(input, output);
    }

    @Override
    public void process() {
        while (input.size() > 0) {
            try {
                Packet p;
                for (int i = 0; i < 10; i++) {
                    p = input.read();
                    String answer = p.getContent();
                    if (answer.equals("A"))
                        System.out.println(p + "回答错误!");
                    else {
                        p.setScore(10);
                        System.out.println(p + "回答正确!");
                    }
                    output.write(p);
                    System.out.println("第 " + p.getPno() + " 题写入管道成功!");
                }
            } catch (Exception e) {
                System.out.println("管道为空!");
                e.printStackTrace();
            }
        }
        System.out.println("------------------------------------------------");
    }
}


  • Pipe(管道)
package filter;

import java.util.ArrayDeque;

public class Pipe {
    private ArrayDeque<Packet> packets = new ArrayDeque<Packet>();

    public void write(Packet packet) {
        packets.addFirst(packet);
    }

    public int size() {
        return packets.size();
    }

    public Packet read() throws Exception {
        if (size() == 0) {
            throw new Exception("管道为空!");
        }
        Packet p = packets.getLast();
        packets.pollLast();
        return p;
    }
}
  • DataSource(数据源)
package filter;

public class DataSource extends Filter {

    public DataSource(Pipe output) {
        super(null, output);
    }

    @Override
    public void process() {
        for (int i = 1; i <= 10; i++) {
            System.out.println("DataSource: 开始扫描第 " + i + " 题...");
            Packet p = new Packet(i);
            double num = Math.random() * 100;
            String option = generateOption(num);
            p.setContent(option);
            System.out.println("第 " + i + " 题写入管道成功!");
            output.write(p);
        }
        System.out.println("------------------------------------------------");
    }

    String generateOption(double i ){
        if(i >= 0 && i < 25)
            return "A";
        else if(i >= 25 && i < 50)
            return "B";
        else if(i >= 50 && i < 75)
            return "C";
        else return "D";
    }
}
  • DataSink(数据池)
package filter;

import java.util.ArrayDeque;

public class DataSink extends Filter {
    protected ArrayDeque<Packet> received = new ArrayDeque<Packet>();

    public DataSink(Pipe input) {
        super(input, null);
    }

    public int size() {
        return received.size();
    }

    @Override
    public void process() {
        try {
            System.out.println("进入数据池!");
            Packet p;
            int score = 0;
            for (int i = 0; i < 10; i++) {
                p = input.read();
                score += p.getScore();
            }
            System.out.println("总成绩为" + score);
        } catch (Exception e) {
            System.out.println("管道为空!");
            e.printStackTrace();
        }
    }
}


  • TestPipes(测试类)
package filter;

public class TestPipes {
    public static void main(String[] args) {
        Pipe pipe1 = new Pipe();
        Pipe pipe2 = new Pipe();
        DataSource source = new DataSource(pipe1);
        source.process();
        FilterImpl filter = new FilterImpl(pipe1, pipe2);
        filter.process();
        DataSink sink = new DataSink(pipe2);
        sink.process();
    }
}

运行结果:

image.png
image.png

相关文章

网友评论

      本文标题:客观题型自动阅卷系统(管道过滤器模式)

      本文链接:https://www.haomeiwen.com/subject/iyxnvctx.html