首页 > 编程语言 >基于Java面向对象思想对个人项目的深度分析

基于Java面向对象思想对个人项目的深度分析

时间:2023-09-21 18:45:13浏览次数:40  
标签:Java int 生成 面向对象 num numbers 深度 new finalStr

基于Java面向对象思想对个人项目的深度分析

一、摘要

本文站在java面向对象思想的角度,深入研究了GJH同学Java中小学数学卷子自动生成程序的工程代码。通过对核心类、继承与多态、封装与解耦等面向对象思想和生成题目算法进行了深度分析,全面探讨了系统的优缺点与改进空间。

关键字:java面向对象思想、算法、字符串、io流。

二、面向对象设计与实现

2.1 模块化设计与核心类

深入剖析核心类的设计:本项目以模块化设计为基础,共有Application、User、IO、Utils、Question、QuestionIml六个类,登录检查、文件操作、生成题目三大主要功能分别用不同的类实现,体现了面向对象封装思想的高内聚、低耦合的特点;Question和QuestionIml体现了继承关系的合理应用,但QuestionIml类过于臃肿,在一个类里面实现了生成小学、初中、高中题目的三种方法,从面向对象的角度分析,不利于今后的扩展和维护;同时,对于User类的定义不够精确,login()方法本应属于客户端的一个模块,却定义在了User类里。

public interface Qustion {

public void createPrimaryTests(int num);

public void createJuniorTests(int num);

public void createSeniorTests(int num);

public void generate(int level, int num);

}

三、核心算法剖析

3.1随机性与灵活性

系统通过引入随机数和种子的方法生成随机的操作数和操作符,并灵活使用字符串拼接的操作来生成题目,保证了生成的题目丰富多样。同时,通过适应不同的学科等级,实现了灵活的生成策略,使得系统具有一定的适应性和可配置性。另外,通过设计查重算法也避免了生成相同的题目,不足之处在于没有筛选掉a+b=b+a的重复题目。

for (int i = 0; i < num; i++) {

StringBuffer finalStr = new StringBuffer();

//...

//4.拼接算术符号

for (int j = 0; j < numbers - 1; j++) {

finalStr.append(operands[j] + signs[random.nextInt(4)]);

}

finalStr.append(operands[numbers - 1] + "=");

//5.判断是否重复,如果重复则重新生成

boolean isRepeated = Utils.repetitionCheck(finalStr.toString());

//...

}

3.2异常处理与健壮性

在代码中,针对用户的输入和各种可能的情况考虑到了详细的异常处理。例如,在用户登录时,通过判断输入是否合法,避免了程序崩溃或进入死循环的情况,提升了系统的健壮性;针对用户不同的命令如:切换模式、生成题目、重新登陆使用try{}catch{}结构进行异常处理。

try {

int num = Integer.parseInt(input);

if (num == -1) {

//...

} catch (NumberFormatException e) {

int levelNum = changeLevel(input);

if (levelNum != -1) {

creatingInterface(levelNum);

}

}

四、改进空间

4.1用户信息存储

在本项目中,用户账号有"张三1"-"王五3",用户规模相对较小,然而我们考虑到系统的未来拓展性与应用广度,因此可以考虑将用户的账号、密码以及用户类型等信息记录在一个独立的txt文件中。在程序运行时,通过读文件的方式获取用户信息,从而实现了对用户信息的动态管理与灵活扩展。这种设计方案不仅有助于系统的维护与扩展,也提高了系统的可用性与可维护性。

 

4.2题目生成方法

考虑到面向对象中的单一职责原则,涉及到小学初中高中的题目生成方法全部内聚在同一个类中,代码的代码的可维护性和扩展性较低,今后需要更改方法容易出现bug,应该将三种方法拆开,设置PrimarySchool、MiddleSchool、HighSchool三个类分别实现,这种拆分设计也符合单一职责原则,使得各个类的职责更加清晰明确。

五、详细代码分析

定义了一个generateParentheses方法,这段代码根据随机数来增加前括号和后括号并使用相应的flagKuo数组相应的元素来进行标记

定义了一个generateSpecialSigns1方法,这段代码根据随机数生成特殊符号(平方符号或平方根符号),并将它们添加到名为operands的数组中的随机位置。同时,代码确保同一位置不会多次生成相同的特殊符号

定义了一个writeIntoTxt方法,这段代码的功能是将一组题目写入到一个文本文件中,文件的路径根据当前用户和时间动态生成。文件的内容来源于传入的questions数组。同时,代码对文件的创建和写入过程进行了异常处理。特色在于灵活的使用到了java文件io流这种技术,有效地将数据保存到本地。并且采用了BufferedWriter类缓冲流,功能效率上比起一般的流更加地好,其类内部维护了一个缓冲区,可以一次性写入多个字符到缓冲区,减少了实际写入磁盘或网络的次数,从而提高了写入性能。

定义了一个readallTxt方法,这段代码的功能是读取一个账号下出国的所有题目,如果不存在的话先创建文件,并且使用了set容器进行查重。同时,代码对文件的创建和读入过程进行了异常处理。特色在于灵活的使用到了java文件io流这种技术,有效地将数据保存到本地。并且采用了BufferedReader类缓冲流,功能效率上比起一般的流更加地好,其类内部维护了一个缓冲区,可以一次性写入多个字符到缓冲区,减少了实际写入磁盘或网络的次数,从而提高了写入性能。

定义了一个getCurrTime方法,通过获取当前时间来创建以时间命名的txt文件

 

定义了一个changeLevel方法,方便用户在得到想要的题目后切换模式再一次进行出题 

定义了一个creatingInterfacefangfa,这段代码的主要功能是根据用户在登陆成功以后的不同指令做出应答,并完成相应的指令,逻辑清晰的代码思路体现出了作者严谨缜密的思维,完成了所有预期的功能。

六、测试结果分析

小学题目,实现了"+、-、*、/"的题目 

初中题目:带有根号或者平方的题目

 高中题目:带有sin、cos、tan的题目

七、实验感受

通过本次个人项目,对学习过的面向对象这门课有了更加真切的感受,在编程的过程中对于面向对象的封装、继承、多态有了更好的体会,并且也在这次动手实验编程的过程中熟悉了java的更多操作比如字符串、io流相关的知识。在项目过程中遇到不同的 新的问题、挑战,我们要时刻保持积极乐观的态度去面对,这样才能更好地提升我们自己的水平。

 八、代码原件

 8.1QuestionImpl源代码

public class QustionImpl implements Qustion {

  String[] signs = {"+", "-", "*", "/"};
  String[] operands;
  /**
   * 对应位置是否包含括号,只有同时包含才非法
   */
  boolean[] flagsKuo;

  /**
   * 对应位置是否有拼音
   */
  boolean[] flagsPingfang;
  /**
   * 对应位置是否有根号
   */
  boolean[] flagsGeng;
  /**
   * 对应位置是否有三角函数
   */
  boolean[] flagsTrigonometricFunc;
  Random random = new Random();


  @Override
  public void generate(int level, int num) {
    switch (level) {
      case 0:
        this.createPrimaryTests(num);
        break;
      case 1:
        this.createJuniorTests(num);
        break;
      case 2:
        this.createSeniorTests(num);
        break;
      default:
    }
  }

  @Override
  public void createPrimaryTests(int num) {
    // 使用当前时间作为随机种子,避免生成的序列相同
    long seed = System.currentTimeMillis();
    random.setSeed(seed);
    String[] strs = new String[num];
    for (int i = 0; i < num; i++) {
      StringBuffer finalStr = new StringBuffer();
      //操作数个数
      int numbers = random.nextInt(4) + 2;
      operands = new String[numbers];
      flagsKuo = new boolean[numbers];
      //1.生成操作数
      for (int j = 0; j < numbers; j++) {
        //生成1-100的数字
        operands[j] = String.valueOf(random.nextInt(100) + 1);
      }
      //2.生成括号,长度>=3才生成
      if (numbers >= 3) {
        generateParentheses(numbers);
      }
      //3.拼接算术符号
      for (int j = 0; j < numbers - 1; j++) {
        finalStr.append(operands[j] + signs[random.nextInt(4)]);
      }
      finalStr.append(operands[numbers - 1] + "=");
      //4.判断是否重复,如果重复则重新生成
      boolean isRepeated = Utils.repetitionCheck(finalStr.toString());
      if (isRepeated) {
        System.out.println("题目重复");
        i--;
        continue;
      }
      strs[i] = "题目" + (i + 1) + " : " + finalStr.toString();
    }
    //写入txt
    Io.writeIntoTxt(strs);
  }


  @Override
  public void createJuniorTests(int num) {
    // 使用当前时间作为随机种子,避免生成的序列相同
    long seed = System.currentTimeMillis();
    random.setSeed(seed);
    String[] strs = new String[num];
    for (int i = 0; i < num; i++) {
      StringBuffer finalStr = new StringBuffer();
      //操作数个数
      int numbers = random.nextInt(5) + 1;
      operands = new String[numbers];
      flagsKuo = new boolean[numbers];
      flagsPingfang = new boolean[numbers];
      flagsGeng = new boolean[numbers];
      //1.生成操作数
      for (int j = 0; j < numbers; j++) {
        operands[j] = String.valueOf(random.nextInt(100) + 1);
      }
      //2.生成根号、平方
      generateSpecialSigns1(numbers);
      //3.生成括号,长度>=3才生成
      if (numbers >= 3) {
        generateParentheses(numbers);
      }
      //4.拼接算术符号
      for (int j = 0; j < numbers - 1; j++) {
        finalStr.append(operands[j] + signs[random.nextInt(4)]);
      }
      finalStr.append(operands[numbers - 1] + "=");
      //5.判断是否重复,如果重复则重新生成
      boolean isRepeated = Utils.repetitionCheck(finalStr.toString());
      if (isRepeated) {
        System.out.println("题目重复");
        i--;
        continue;
      }
      strs[i] = "题目" + (i + 1) + " : " + finalStr.toString();
    }
    Io.writeIntoTxt(strs);
  }

  //生成num个高中题目
  @Override
  public void createSeniorTests(int num) {
    long seed = System.currentTimeMillis();
    random.setSeed(seed);
    String[] strs = new String[num];
    for (int i = 0; i < num; i++) {
      StringBuffer finalStr = new StringBuffer();
      int numbers = random.nextInt(5) + 1;
      operands = new String[numbers];
      flagsKuo = new boolean[numbers];
      flagsPingfang = new boolean[numbers];
      flagsGeng = new boolean[numbers];
      flagsTrigonometricFunc = new boolean[numbers];
      for (int j = 0; j < numbers; j++) {
        operands[j] = String.valueOf(random.nextInt(100) + 1);
      }
      //2.生成三角函数
      generateTrigonometricFunc(numbers);
      //3.生成平方、根号
      generateSpecialSigns1(numbers);
      //4.生成括号,长度>=3才生成
      if (numbers >= 3) {
        generateParentheses(numbers);
      }
      //5.拼接算术符号
      for (int j = 0; j < numbers - 1; j++) {
        finalStr.append(operands[j] + signs[random.nextInt(4)]);
      }
      finalStr.append(operands[numbers - 1] + "=");
      //6.判断是否重复,如果重复则重新生成
      boolean isRepeated = Utils.repetitionCheck(finalStr.toString());
      if (isRepeated) {
        System.out.println("题目重复");
        i--;
        continue;
      }
      strs[i] = "题目" + (i + 1) + " : " + finalStr.toString();
    }
    Io.writeIntoTxt(strs);
  }

  /**
   * 生成括号,参数为:操作数个数 生成原则,操作数个数>=3时生成,个数为1至numbers-2;生成一个长度2<=len<=numbers-1
   * 起始位置:start<numbers-len,这样结束位置<=start+len<numbers 注意,生成(号前,该位置不能有); 生成)号前,该位置不能有(
   *
   * @param numbers
   */
  public void generateParentheses(int numbers) {
    //个数为1至numbers-2
    int kuohaoNums = random.nextInt(numbers - 2) + 1;
    while (kuohaoNums > 0) {
      //生成一个长度2<=len<=numbers-1
      int len = random.nextInt(numbers - 2) + 2;
      int start = random.nextInt(numbers - len), end = start + len - 1;
      //如果首尾重复了,则生成失败
      if (flagsKuo[start] && flagsKuo[end]) {
        kuohaoNums--;
        continue;
      }
      operands[start] = "(" + operands[start];
      operands[end] += ")";
      //设置标记,已经加过括号了
      flagsKuo[start] = true;
      flagsKuo[end] = true;
      kuohaoNums--;
    }
  }


  /**
   * 生成平方和根号,最多生成numbers个(限制难度)
   *
   * @param numbers
   */
  public void generateSpecialSigns1(int numbers) {
    int totals = random.nextInt(numbers) + 1;
    for (int i = 0; i < totals; i++) {
      int position = random.nextInt(numbers);
      //一半概率生成平方,并且他之前没生成过平方
      if (random.nextBoolean()) {
        if (!flagsPingfang[position]) {
          operands[position] += "²";
          flagsPingfang[position] = true;
        } else {
          continue;  //重复了,继续
        }
      } else {
        if (!flagsGeng[position]) {
          operands[position] = "√" + operands[position];
          flagsGeng[position] = true;
        } else {
          continue;  //重复了,继续
        }
      }
    }
  }

  /**
   * 生成三角函数,最多生成numbers-1个,并且同一位置不重复生成(限制难度)
   *
   * @param numbers
   */
  public void generateTrigonometricFunc(int numbers) {
    int totals = random.nextInt(numbers);
    for (int i = 0; i < totals; i++) {
      int position = random.nextInt(numbers);
      int state = random.nextInt(3);
      //生成sin
      if (state == 0 && !flagsTrigonometricFunc[position]) {
        operands[position] = "sin" + operands[position];
        flagsTrigonometricFunc[position] = true;
      }
      //生成cos
      else if (state == 1 && !flagsTrigonometricFunc[position]) {
        operands[position] = "cos" + operands[position];
        flagsTrigonometricFunc[position] = true;
      }
      //生成tan
      else if (state == 2 && !flagsTrigonometricFunc[position]) {
        operands[position] = "tan" + operands[position];
        flagsTrigonometricFunc[position] = true;
      }
    }
  }
}

 

 

 

 

标签:Java,int,生成,面向对象,num,numbers,深度,new,finalStr
From: https://www.cnblogs.com/Protsin/p/17720481.html

相关文章

  • 携程ASE加密解密 java python
    java代码packagecom.example.trip_vip;importcom.alibaba.fastjson.JSON;importcom.alibaba.fastjson.JSONObject;importjavax.crypto.Cipher;importjavax.crypto.spec.IvParameterSpec;importjavax.crypto.spec.SecretKeySpec;importjava.io.UnsupportedEncod......
  • JavaScript Library – Svelte
    前言上一回我介绍了 Alpine.js。作为我开发企业网站draft版本的renderengine。用了一阵子后,我觉得它真的非常不好用。所以打算换一个。前端有好几个framework/library/compiler都可以用来做MVVMrenderengine。比如Angular、React、Vue、LIt、Solid、Qwik、Svelt......
  • 携程 3DES加密解密 java python
    javapackagecom.example;importorg.springblade.core.tool.utils.*;importjavax.annotation.Nullable;importjavax.crypto.Cipher;importjavax.crypto.SecretKeyFactory;importjavax.crypto.spec.DESKeySpec;importjava.util.Objects;publicclassDES3{......
  • java循环
    publicclassTestWhile1{publicstaticvoidmain(String[]args){/*intnum=1;//条件初始化intresult=1;while(num<=13){//条件判断result*=num;//循环体num+=2;//num++//迭代}System.out.println(result);*//*intnu......
  • java抽象类和抽象方法
    1.抽象的概念 2.抽象类和抽象方法的使用1//抽象方法和抽象类的格式:2/*抽象方法:就是加上abstract关键字,然后去掉大括号,直接分号结束;3抽象类:抽象方法所在的类,必须是抽象类才行,在class之前的写上abstract即可。45如何使用抽象类和抽象方法61.不能直接创建(new)抽象类对......
  • 面向对象_向下转型_向上转型
    1packagecom.msb9;23publicclassAnimal{4intage;5publicvoidshout(){6System.out.println("小动物在大声叫");7}8}1packagecom.msb9;23publicclassPigextendsAnimal{4doubleweight;5publicvoidsh......
  • java开发之个人微信的二次开发
    简要描述:设置个人头像请求URL:http://域名地址/sendHeadImage请求方式:POST请求头Headers:Content-Type:application/jsonAuthorization:Authorization值(登录获取码信息接口中返回的认证信息值)参数:参数名必选类型说明wId是string登录实例标识path是string图片url链接返回数据:参数名类型......
  • org/springframework/boot/maven/RepackageMojo has been compiled by a more recent
    项目场景:项目中执行clean,再执行install时报错,错误如下org/springframework/boot/maven/RepackageMojohasbeencompiledbyamorerecentversionoftheJavaRuntime(classfileversion61.0),thisversionoftheJavaRuntimeonlyrecognizesclassfileversionsupt......
  • java日期时间类现在(java8及以后版本)推荐使用java.time 包中的类
    以下信息由AI模型"文心一言"提供,仅供参考:在Java8之后,推荐使用新的日期和时间API,即java.time包中的类。主要有以下原因:更好的设计和功能:新的日期和时间API在设计和功能上都更优。它包括时间、日期、时间间隔等更全面的表示,并支持更准确的计算和格式化。更全面的时间......
  • JavaScript实现数组对象去重
    有多种实现方式:一、使用 Set 对象:1Array.from(new Set(array))该方法会先创建一个 Set 对象,然后再使用 Array.from 方法将 Set 对象转换为数组,因为 Set 对象不允许有重复的元素,所以这样可以实现去重的效果。但是,如果数组中的元素是对象,Set 对......