案例分析:百分制转等级制程序演进

某学校为响应国家教学评估体制改革,现预备按表 Tab1.1 所示方案将百分制成绩转化为等级制成绩,试给出转换办法。

百分制转等级制1

Tab1.1方案实现:

package transf_CentesimalSys_to_GradationSys;
import java.util.Scanner;
/**
 * @see 百分制转等级制
 * @version 1.0
 * @author JustBeGeek
 */
public class Transform_1 {
    public static void main(String[] args){
        Scanner input=new Scanner(System.in);
        System.out.println("请输入你的成绩:");
        int mark=input.nextInt();
        String grade="";
        /*————————————————————————-*/
        if(mark>=90)
            grade+='A';
        else if(mark>=80)
            grade+='B';
        else if(mark>=70)
            grade+='C';
        else if(mark>=60)
            grade+='D';
        else
            grade+='E';
       /*————————————————————————-*/
        System.out.println("在转换方案(Ⅰ)下,您的成绩是:"+grade); 
    }
}


若该学校获悉市教育局预备按方案 Tab1.2 统一实施 百分制成绩转等级制成绩 改革,试给出对应转换办法。

百分制转等级制2

分析:Tab1.2  方案 较 Tab1.1 方案 改变之处仅为每个等级对应的分数段发生改变, 而程序  Transform_1  为适应 Tab1.2  方案须修改其多路比较中的所有分界值常量(90、80以及70等),而这样的修改幅度较大,容易产生bugs,且适应性差(在下一次对应分数段改变时仍需要冒此类风险进行修改)。也就是说,转换方案的每一次变动都将令程序  Transform_1 不得不进行大幅度修改以适应新方案,而这样的修改仅能暂时维持程序满足方案要求。究其原因,我们不难发现是由于程序  Transform_1  在其多路比较中直接引入分界值常量,而分界值在转换方案变动时是不稳定的。

方案:将分界值常量有序存储于数组中,在多路比较中采用存储了相应分界值常量的数组分量作为比较基准;发生对应分数段改变时仅需更新数组中的有序常量集

Tab1.2 方案实现(等级名称亦可调整)

package transf_CentesimalSys_to_GradationSys;
import java.util.Scanner;
/**
 * @see 百分制转等级制
 * @version 2.0
 * @author JustBeGeek
 */
public class Transform_2 {
    private static final int[] GRADATION={85,75,65,55};
    private static final String[] GRADE={"A","B","C","D","E"};
    public static void main(String[] args){
        Scanner input=new Scanner(System.in);
        System.out.println("请输入你的成绩:");
        int mark=input.nextInt();
        String grade="";
        /*————————————————————————-*/
        if(mark>=GRADATION[0])
            grade+=GRADE[0];
        else if(mark>=GRADATION[1])
            grade+=GRADE[1];
        else if(mark>=GRADATION[2])
            grade+=GRADE[2];
        else if(mark>=GRADATION[3])
            grade+=GRADE[3];
        else
            grade+=GRADE[4];
        /*————————————————————————-*/
        System.out.println("在转换方案(Ⅱ)下,您的成绩是:"+grade);
    }
}

该学校为更详细了解学生成绩分布,现准备在市教育局方案基础上制定内部方案 Tab1.3,试给出转换办法。

百分制转等级制

分析:Tab1.2 到 Tab1.3 的方案迁移,造成等级划分更细,即出现了更多的等级。若为适应新的内部方案而对 程序 Transform_2 进行维护,我们发现其工作量较“ 程序 Transform_1 为适应 Tab1.1 至Tab1.2 的迁移维护”更大也更繁琐,这样的维护与专门为 Tab1.3 构建新程序有过之而无不及,于是,我决定进行第二次通用化处理,即如何消除常量集规模对程序多路选择路数的影响?

方案:①数组有序存储分界值常量集;②采用循环测试代替多路选择测试。

Tab1.3 方案实现:

package transf_CentesimalSys_to_GradationSys;
import java.util.Scanner;
/**
 * @see 百分制转等级制
 * @version 3.0
 * @author JustBeGeek
 */
public class Transform_3 {
    /**
     * @see 方案集
     *
     */
    /*Tab1.2方案*/
    private static final int[] GRADATION1_2={85,75,65,55};
    private static final String[] GRADE1_2= {"A","B","C","D","E"};  
    /*Tab1.3方案*/
    private static final int[] GRADATION1_3={95,85,80,75,65,60,55};
    private static final String[] GRADE1_3={"A+","A-","B+","B-","C+","C-","D+","D-","E"};
    public static void main(String[] args){
        Scanner input=new Scanner(System.in);
        System.out.println("请输入你的成绩:");
        int mark=input.nextInt();
        String grade="";
        /*————————————————————————-*/
        boolean inner=false;//此变量标定是否按内部方案执行,默认按市教育局方案执行
        if(inner)
            grade+=whichGrade(GRADATION1_2,GRADE1_2,mark);
        else
            grade+=whichGrade(GRADATION1_3,GRADE1_3,mark);
        /*————————————————————————-*/
        System.out.println("在转换方案(Ⅲ)下,您的成绩是:"+grade);
    }
    public static String whichGrade(int[] gradation,String[]  grade,int mark){
        int i=0;
        for(;i<gradation.length;i++){
            if(mark>=gradation[i])
                break;
        }
        return grade[i];
    }      
}      

分析:在维护程序 Transform_3 时,我们发现其用两个数组分别存储同一方案中的两组常量集(分数分界点集、等级符号集),并在  函数 whichGrade 中实现由分数分界点集到等级符号集的映射的设计 人为地割裂了同属一个方案的两组关联数据,造成它们间的映射关系不够显著(模糊了函数构造与函数求值),而且维护时更需十分注意两组关联赋值的顺序是否对应。为了使维护程序更加直观、方便,我决定采用了以下方法改造:①构造关系节点 Mapping ;② 利用 Mapping 型数组独立存储各转换方案(构造函数);③ 函数 whichGrade 直接将方案( Mapping 型数组)作为参数,并根据方案找到分数对应的等级(函数求值)。

Tab1.3 方案改进实现:

package transf_CentesimalSys_to_GradationSys;
import java.util.Scanner;
import transf_CentesimalSys_to_GradationSys.Mapping;
/**
 * @see 百分制转等级制
 * @version 3.1
 * @author JustBeGeek
 */
public class Transform_3_1 {
    /**
     * @see 方案集
     * @see 方案:分界值常量集到等级常量集的关系。
     */
    /*Tab1.2方案*/
    private static final Mapping[] Tab1_2={
        new Mapping(85,"A"),new Mapping(75,"B"),
        new Mapping(65,"C"),new Mapping(55,"D"),
        new Mapping(0,"E"),
    };
    /*Tab1.3方案*/
    private static final Mapping[] Tab1_3={
        new Mapping(95,"A+"),new Mapping(85,"A-"),
        new Mapping(80,"B+"),new Mapping(75,"B-"),
        new Mapping(70,"C+"),new Mapping(65,"C-"),
        new Mapping(60,"D+"),new Mapping(55,"D-"),
        new Mapping(0,"E")};
    public static void main(String[] args){
        Scanner input=new Scanner(System.in);
        System.out.println("请输入你的成绩:");
        int mark=input.nextInt();
        String grade="";
        /*————————————————————————-*/
        boolean inner=false;//此变量标定是否按内部方案执行,默认按市教育局方案执行
        if(inner)
            grade+=whichGrade(Tab1_2,mark);
        else
            grade+=whichGrade(Tab1_3,mark);
        /*————————————————————————-*/
        System.out.println("在转换方案(Ⅲ)下,您的成绩是:"+"grade");
    }
    /**
     * @see 分数mark按方案schem执行转换
     * @param schem 方案
     * @param mark 分数
     * @return 等级
     */
    private static String whichGrade(Mapping[] schem,int mark){
        int i=0;
        for(;i<schem.length;i++){
            if(mark>=schem[i].getGradation())
                break;
        } 
        return schem[i].getGrade();
    }
}
调用类:

package transf_CentesimalSys_to_GradationSys;
/**
 * @see 关系节点
 * @author JustBeGeek
 */
public class Mapping{
        private int gradation;
        private String grade;
        public Mapping(int gradation,String grade){
            this.gradation=gradation;
            this.grade=grade;
        }
        public int  getGradation(){
            return gradation;
        }
        public  String getGrade(){
            return grade;
        }      
    }



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值