写完以后发现我勒个去,150+行代码的一个方法,参数快20个了,想refactor extract method 发现也不是好办法,参数太多了,而且如果分小段的if去refactor也不行啊,里面有for循环,还有break的
求助 怎么能优化?

解决方案 »

  1.   

    有for循环 然后很多地方break 都不能单独拉出一个方法来,郁闷啊
      

  2.   

    public void autoLevelUp(Packet packet, ClientSession session){
    int tryValue = 0;//自动升级使用的元气值
    int serial = packet.getInt();
    int jingmaiId = packet.getInt();
    int jingmaiSkillLevel = packet.getInt();//当前经脉等级
    int hopeLevel = packet.getInt();//期望等级
    int skillIds = packet.getInt();
    int curTag = packet.get();
    int curJingmai = packet.get();
    int isAutoUseIMoney = packet.getByte();
    PlayerEx player = (PlayerEx) session.getClient();
    if(player != null){
    int iMoneyRestValue = player.getAccount().getIMoney()*10;//元宝换算成元气的值
    int tryIMoney = 0;//自动升级使用的元宝
    boolean isUseIMoney = false;
    int tempRestValue = player.getRestvalue().value;//临时记录玩家元气值
    int tempLevel = 0;
    Skill perSkill = null;
    int LevelUp = 0;//最终的经脉等级
    int canLevelUpCount = 0;
    int  = 0;
    if(isAutoUseIMoney == 1){
    int levelCount = hopeLevel - jingmaiSkillLevel;
    canLevelUpCount = levelCount;
    LevelUp = hopeLevel;
    }else{
    int levelCount = hopeLevel - jingmaiSkillLevel;
    for(int i = 0; i < levelCount; i++){
    if(player.getRestvalue().value - jingmaiProb.get(jingmaiSkillLevel).needValue*(i+1) < 0){
    LevelUp = i + jingmaiSkillLevel;
     = 1;
    break;
    }
    }
    if( == 0){
    LevelUp = hopeLevel;
    }
    canLevelUpCount = LevelUp - jingmaiSkillLevel;
    }
    if(canLevelUpCount > 0){
    SkillServiceEx skillService = (SkillServiceEx) Platform.getAppContext().get(SkillService.class);
    JingmaiPoint jingmai = getJingmai(jingmaiId);
    SkillsEx skills = (SkillsEx) player.getSkills();
    for(int i = 0; i < canLevelUpCount; i++){
    Random random = new Random();
    int rand = random.nextInt(100) + 1;
    //点自动提升
    if(rand <= jingmaiProb.get(jingmaiSkillLevel+i).upProb){
    //几率命中
    Skill skill = skills.getJingmaiByGroupId(jingmaiId);
    Platform.getLog(LogEx.class).logJingmai(player, jingmaiId, jingmaiSkillLevel + i, 1);
    if (skill != null) {
    try{
    perSkill = skillService.getSkill(skill.getGroupId(), jingmaiSkillLevel + 1 +i);
    }catch(Exception e){
    e.printStackTrace();
    ErrorHandler.sendErrorMessage(player.getSession(), -1,OpCodeEx.TALENT_CHANGEPOINT_CLIENT, "技能已到最高级别");
    LevelUp = i + jingmaiSkillLevel;
    break;
    }
    if (perSkill != null && perSkill.getLevel() != 0) {
    skills.removeJingmai(player, skill.getGroupId(), skill.getLevel());
    skills.addJingmai(perSkill,player);
    //已经升级了
    Platform.getLog(LogEx.class).logJingmaiOk(player, jingmaiId, jingmaiSkillLevel + i, 1);
    if(tempRestValue - jingmaiProb.get(jingmaiSkillLevel+i).needValue >= 0){
    tempRestValue -= jingmaiProb.get(jingmaiSkillLevel+i).needValue;
    tryValue += jingmaiProb.get(jingmaiSkillLevel+i).needValue;
    }else{
    tempLevel = i;
     = 1;
    LevelUp = tempLevel + jingmaiSkillLevel;
    if(isAutoUseIMoney == 1){
    if(iMoneyRestValue - jingmaiProb.get(jingmaiSkillLevel+i).needValue*3600 >= 0){
    iMoneyRestValue -= jingmaiProb.get(jingmaiSkillLevel+i).needValue*3600;
    tryIMoney += jingmaiProb.get(jingmaiSkillLevel+i).needValue*3600;
     = 0;
    isUseIMoney = true;
    }else{
     = 2;
    break;
    }
    }else{
    break;
    }
    }
    } else {
    ErrorHandler.sendErrorMessage(player.getSession(), -1,OpCodeEx.TALENT_CHANGEPOINT_CLIENT, "技能已到最高级别");
    break;
    }
    } else {
    //经脉从0级到1级
    Skill parentSkill = SkillServiceEx.getSkill(skillIds);
    perSkill = skillService.getSkill(parentSkill.getGroupId(),1);
    skills.addJingmai(perSkill, player);
    if(tempRestValue - jingmaiProb.get(jingmaiSkillLevel+i).needValue >= 0){
    tempRestValue -= jingmaiProb.get(jingmaiSkillLevel+i).needValue;
    tryValue += jingmaiProb.get(jingmaiSkillLevel+i).needValue;
    }else{
    tempLevel = i;
     = 1;
    LevelUp = tempLevel + jingmaiSkillLevel;
    if(isAutoUseIMoney == 1){
    if(iMoneyRestValue - jingmaiProb.get(jingmaiSkillLevel+i).needValue*3600 >= 0){
    iMoneyRestValue -= jingmaiProb.get(jingmaiSkillLevel+i).needValue*3600;
    tryIMoney += jingmaiProb.get(jingmaiSkillLevel+i).needValue*3600;
     = 0;
    isUseIMoney = true;
    }else{
     = 2;
    break;
    }
    }else{
    break;
    }
    }
    Platform.getLog(LogEx.class).logJingmaiOk(player, jingmaiId, jingmaiSkillLevel + i, 1);
    }
    }else{
    //失败
    if(tempRestValue - jingmaiProb.get(jingmaiSkillLevel+i).needValue >= 0){
    tempRestValue -= jingmaiProb.get(jingmaiSkillLevel+i).needValue;
    tryValue += jingmaiProb.get(jingmaiSkillLevel+i).needValue;
    }else{
    LevelUp = i + jingmaiSkillLevel;
     = 1;
    if(isAutoUseIMoney == 1){
    if(iMoneyRestValue - jingmaiProb.get(jingmaiSkillLevel+i).needValue*3600 >= 0){
    iMoneyRestValue -= jingmaiProb.get(jingmaiSkillLevel+i).needValue*3600;
    tryIMoney += jingmaiProb.get(jingmaiSkillLevel+i).needValue*3600;
     = 0;
    isUseIMoney = true;
    }else{
     = 2;
    break;
    }
    }else{
    break;
    }
    }
    i--;
    }
    }
    PlayerTransaction tx = player.newTransaction("JINGMAIAUTOLEVELUP");
    try {
    player.requestCurrency(tx, CurrencyCodes.CURRENCY_YUANQI, tryValue, true);
    tx.commit();
    } catch (NoEnoughValueException e) {
    ErrorHandler.sendErrorMessage(player.getSession(), -1,OpCodeEx.TALENT_CHANGEPOINT_CLIENT, "元气不足");
    tx.rollback();
    LevelUp = tempLevel + jingmaiSkillLevel;
    }
    if(isUseIMoney){
    int decValue = 0;
    try {
    decValue = player.decBIMoneyFThenIMoney(tryIMoney/10, LogItem.TALENT_ITEM/*.TALENT_ITEM*/, 1, tx);
    tx.commit();
    } catch (NoEnoughIMoneyException e1) {
     = 2;
    LevelUp = tempLevel + jingmaiSkillLevel;
    tx.rollback();
    }
    player.addTodayPayBoundIMoney(decValue);
    }
    Packet pt = new Packet(OpCodeEx.JINGMAI_AUTOLEVELUP_SERVER);
    pt.put(LevelUp);
    pt.put(curTag);
    pt.put(curJingmai);
    pt.putString(jingmai.skill.getName());
    String curDesStr = skillService.getSkill(jingmai.skill.getGroupId(), LevelUp).getDesc(player);
    Skill nextSkill = skillService.getSkill(jingmai.skill.getGroupId(), LevelUp + 1);
    String nextDescStr = "";
    if(nextSkill != null){
    nextDescStr = nextSkill.getDesc(player);
    }
    pt.putString(curDesStr);
    pt.putString(nextDescStr);
    player.send(pt);
    if( == 1){
    ErrorHandler.sendErrorMessage(player.getSession(), -1,OpCodeEx.TALENT_CHANGEPOINT_CLIENT, "您的元气不足以提升至预期等级,已提升到" + LevelUp + "级");
    }else if( == 2){
    ErrorHandler.sendErrorMessage(player.getSession(), -1,OpCodeEx.TALENT_CHANGEPOINT_CLIENT, "您的元宝不足以提升至预期等级,已提升到" + LevelUp + "级");
    }else{
    ErrorHandler.sendErrorMessage(player.getSession(), -1,OpCodeEx.TALENT_CHANGEPOINT_CLIENT, "经脉已提升级别");
    }
    }else{
    ErrorHandler.sendErrorMessage(player.getSession(), -1,OpCodeEx.TALENT_CHANGEPOINT_CLIENT, "元气值不足");
    }
    }

    }
      

  3.   

    刚才我自己优化了一下,现在是将近200行代码,我现在缩成100行了,提出一些if里的方法,break的地方写成return true,然后方法接受返回的地方 如果是true就break,这样大家觉得可以吗?
      

  4.   

    在C语言中,参数多了就要封装为结构体
    java封装成对象啊
      

  5.   

    按功能细化,最起码也能够分为几个独立的方法或者services
      

  6.   

    嗯嗯,看了一会,没看懂。我觉得变量命名得不错
    还有我不喜欢if后面的括号写在跟if同一行。
      

  7.   

    这代码··· 还没深刻理解oop````
      

  8.   

    参数多,如果传不方便,就用一个list代替,但是需要说明list中数据的位置,是做什么的
      

  9.   

    把参数 变成一个实体对象类MethodParameter 直接传对象
      

  10.   

    这个,代码太乱,我就不动手了。
    楼主应该尝试 把数据和行为  分开。
    就是说,把 数据 和 指令 分开。首先,将函数里面的变量,进行归类整理。
      属于同一类的数据,封装成一个Java类,用于存储数据。
      比如,你那个packet对象读取出的所有变量,就可以封装成一个类对象。
      这样下来,应该至少有两个类了,这些类都用来存储数据。其次,将函数里面,具有一定功能的代码,分类归纳。
      属于同一方式的功能,封装成一个Java类,用于提供某种方式下的各种功能。
      你所使用的ErrorHandler不就提供错误信息的输出吗 ?
      你可以写一个类,专门用于根据传入的数据对象,完成自动升级的类,
      里面包含多个函数,有升级任务等级的,有升级经脉等级的,等等等等。
      当然,这是我的想法,楼主可以根据实际情况,归纳总结,
      编写一个,或多个这些的类。
      比如,专门将packet对象转换成指定的数据对象的工具类。等等。最后,有了数据对象和行为对象,
      下面的工作,就是将这些对象串联起来,完成整个的业务逻辑咯。
      当然,有经验的程序员,还会根据业务步骤抽象出一条业务链,
      这样可以方便增删业务的某个步骤。祝楼主好运。
      

  11.   

    没细看你的程序,但是看你用到很多if-else,你可以把你的程序画一个程序流程图
    从编译的角度来优化一下,或者重新设计程序。比较推荐后者。前面的太麻烦了!
      

  12.   

    数据参数太多的话可以组成一个对象或者设置成public放在外边,然后按照功能对整个代码进行划分
      

  13.   

    大概数了一下,if + for 的深度最大达到8层,超过三层就不推荐了,8层啊,这段谁要是维护能把人吓死,重构吧~
      

  14.   

    不要把所有功能的挤在一个方法里面,这个方法可以完成很多事情,比如出库模块:
    public void inStore(){
      if(有足够库存){
        //出库
         doOutStore();
      }else{
        //先入库
         doInStore();
        //再出库
         doOutStore();
      }
    }然后doOutStore、doInStore又在其它方法实现,我这个伪代码还可以继续优化的比如,你下面的代码,我觉得就可以抽出来,而且你那代码里面有很多这样的代码。int levelCount = hopeLevel - jingmaiSkillLevel;
                    for(int i = 0; i < levelCount; i++){
                        if(player.getRestvalue().value - jingmaiProb.get(jingmaiSkillLevel).needValue*(i+1) < 0){
                            LevelUp = i + jingmaiSkillLevel;
                             = 1;
                            break;
                        }
                    }
                    if( == 0){
                        LevelUp = hopeLevel;
                    }
                    canLevelUpCount = LevelUp - jingmaiSkillLevel;
      

  15.   

     我感觉  好多变量都不用定义,用到的时候就 对象.getXXX();
      

  16.   

    其实 你 一个 if 就是一个逻辑! 最细化的话,完全可以细化到if,我看你的if都是根据packet 获得的,那完全可以查分多个方法,用什么,然后通过packet获取,这样看起来,也许会简单些!
      

  17.   

    好吧   游戏的代码差不多都是这样   LZ做ios的吗   我见过比你这个还长的。   如果不是本人去优化   会出很多问题  
      

  18.   

    如楼上所说,把参数封装成对象,还有一个就是ifelse多的话,可以用swithcase这样看起来会明朗许多!
      

  19.   

    老大啊.......其实你应该来我们公司的 你review code  我现在维护别人的代码 有个的方法上千行.N多if逻辑判断 N多 for N多try  哎 dao和service分层不明确  有时候会在service中去注入dao 有的会在service是在和service没关系的包中注入 反正言而总之  就是乱.........逻辑上很乱.......经常跑程序需要debug 或则一个方法一个方法的去看