«

不同数据的处理方式其核心思想

MitSeek 发布于 阅读:25


实例代码:

<?php
echo '<pre>';
$_POST = [
    'binary' => [1=>'yes',2=>'no'],
    'single' => [1=>'D'],
    'multiple' => [1=>['A','B','C','D']],
    'fill' => [1=>'下划线']
];

require './common/function.php';
$id = getTestId();
$data = getDataById($id, false);

if(!$data){
    require './view/notFound.html';
    exit;
}

list($count, $score) = getDataInfo($data['data']);

$sum = 0;
$total = [];

// 处理每种题型
foreach($data['data'] as $type => $each){

    switch($type){
        case 'binary':
            // binary题型:数据在 ['data'] 中
            if(isset($each['data'])){
                foreach($each['data'] as $k => $question){
                    $userAnswer = $_POST[$type][$k] ?? '';
                    $correctAnswer = $question['answer'] ?? '';

                    if($userAnswer === $correctAnswer){
                        $total[$type][$k] = true;
                        $sum += $score[$type];
                    } else {
                        $total[$type][$k] = false;
                    }
                }
            }
            break;

        case 'single':
            // single题型:直接遍历
            foreach($each as $k => $question){
                if(is_numeric($k)){ // 确保是题目编号
                    $userAnswer = $_POST[$type][$k] ?? '';
                    $correctAnswer = $question['answer'] ?? '';

                    if($userAnswer === $correctAnswer){
                        $total[$type][$k] = true;
                        $sum += $score[$type];
                    } else {
                        $total[$type][$k] = false;
                    }
                }
            }
            break;

        case 'multiple':
            // multiple题型:特殊处理,只有一个题目
            $userAnswer = $_POST[$type][1] ?? []; // 假设题目编号为1
            $correctAnswer = $each['answer'] ?? [];

            // 多选题比较(忽略顺序)
            sort($userAnswer);
            sort($correctAnswer);

            if($userAnswer === $correctAnswer){
                $total[$type][1] = true;
                $sum += $score[$type];
            } else {
                $total[$type][1] = false;
            }
            break;

        case 'fill':
            // fill题型:直接遍历
            foreach($each as $k => $question){
                if(is_numeric($k)){ // 确保是题目编号
                    $userAnswer = $_POST[$type][$k] ?? '';
                    $correctAnswer = $question['answer'] ?? '';

                    if($userAnswer === $correctAnswer){
                        $total[$type][$k] = true;
                        $sum += $score[$type];
                    } else {
                        $total[$type][$k] = false;
                    }
                }
            }
            break;
    }
}

require './view/total.html';
?>

🎯 核心思想总结

1. 结构化思维 (Structural Thinking)

// 识别并尊重每种题型的数据结构差异
switch($type){
    case 'binary':   // 特殊嵌套结构
    case 'single':   // 直接题目数组  
    case 'multiple': // 单一题目结构
    case 'fill':     // 直接题目数组
}

思想:认识到现实世界数据很少是统一的,需要根据实际结构而不是理想结构来编程。

2. 关注点分离 (Separation of Concerns)

// 每种题型的处理逻辑独立封装
case 'binary':   // 处理两层嵌套数据
case 'single':   // 处理普通题目数据  
case 'multiple': // 处理特殊单一题目
case 'fill':     // 处理填空题目

思想:将复杂问题分解为独立的子问题,每个部分只关注自己的职责。

3. 防御性编程 (Defensive Programming)

// 多重安全检查
if(isset($each['data'])){...}           // 检查键是否存在
if(is_numeric($k)){...}                 // 验证数据类型
$userAnswer = $_POST[$type][$k] ?? '';  // 空值保护
$correctAnswer = $question['answer'] ?? ''; // 默认值处理

思想:不信任任何外部数据,始终验证假设,优雅处理边界情况。

4. 多态思想 (Polymorphic Thinking)

// 相同操作(批改),不同实现
binary:   $userAnswer === $correctAnswer          // 字符串比较
single:   $userAnswer === $correctAnswer          // 字符串比较  
multiple: sort($userAnswer) === sort($correctAnswer) // 数组比较
fill:     $userAnswer === $correctAnswer          // 字符串比较

思想:相同的接口(比较答案),不同的实现方式,根据具体类型选择适当算法。

5. 数据驱动设计 (Data-Driven Design)

// 让数据结构决定处理逻辑
$data['data'] = [
    'binary'   => ['name'=>'判断题', 'score'=>20, 'data'=>[...]],
    'single'   => [1=>['question'=>'...', 'answer'=>'D']],
    'multiple' => ['question'=>'...', 'answer'=>['A','B','C','D']],
    'fill'     => [1=>['question'=>'...', 'answer'=>'下划线']]
];

思想:程序逻辑应该适应数据,而不是强迫数据适应预设逻辑。

🔧 具体设计模式体现

策略模式 (Strategy Pattern)

// 每种题型都是不同的批改策略
interface GradingStrategy {
    public function grade($userAnswer, $correctAnswer);
}

class BinaryGrading implements GradingStrategy {
    public function grade($userAnswer, $correctAnswer) {
        return $userAnswer === $correctAnswer;
    }
}

class MultipleGrading implements GradingStrategy {
    public function grade($userAnswer, $correctAnswer) {
        sort($userAnswer);
        sort($correctAnswer);
        return $userAnswer === $correctAnswer;
    }
}

模板方法模式 (Template Method)

// 相同的处理流程,不同的实现细节
abstract class QuestionType {
    // 模板方法 - 定义算法骨架
    public function process() {
        $this->extractData();
        $this->getUserAnswer();
        $this->compareAnswers();
        $this->calculateScore();
    }

    // 具体步骤由子类实现
    abstract protected function extractData();
    abstract protected function compareAnswers();
}

💡 架构思维亮点

1. 可扩展性设计

// 新增题型只需添加一个case
case 'new_type':
    // 新题型的特殊处理逻辑
    break;

优势:开闭原则 - 对扩展开放,对修改封闭。

2. 容错性设计

// 多层保护确保程序不崩溃
foreach($each as $k => $question){
    if(is_numeric($k)){ // 过滤非题目数据
        $userAnswer = $_POST[$type][$k] ?? ''; // 空值保护
        $correctAnswer = $question['answer'] ?? ''; // 键存在检查
        // ...
    }
}

3. 算法适应性

// 根据数据类型选择比较算法
if(is_array($correctAnswer) && is_array($userAnswer)){
    // 数组比较算法
    sort($correctAnswer);
    sort($userAnswer);
    $isCorrect = ($correctAnswer === $userAnswer);
} else {
    // 字符串比较算法  
    $isCorrect = ($correctAnswer === $userAnswer);
}

🚀 工程实践价值

可维护性可维护性

逻辑清晰:每种题型处理独立,便于理解和修改
错误定位:问题容易追溯到具体题型处理逻辑
测试友好:可以针对每种题型单独测试

可读性

// 代码自文档化 - 从结构就能理解业务
switch($type){
    case 'binary':   // 处理判断题
    case 'single':   // 处理单选题
    case 'multiple': // 处理多选题  
    case 'fill':     // 处理填空题
}

健壮性

通过多重验证确保:
数据结构变化不会导致程序崩溃
用户输入错误不会影响系统稳定性
数据缺失时有合理的默认行为

🌟 思想升华

这个解决方案体现了从 "代码搬运工" 到 "问题架构师" 的思维转变:

从"怎么做"到"为什么这样做" - 理解数据背后的业务含义
从"统一处理"到"差异尊重" - 承认并处理现实世界的不一致性
从"功能实现"到"系统设计" - 考虑扩展性、维护性、健壮性
从"编码"到"工程" - 将编程视为系统工程而非单纯语法运用

编程思想