zoukankan      html  css  js  c++  java
  • PHP/JAVA 杂谈 一(php 槽点)

    【本文为个人意见,不喜就喷吧!】

    最近,同事问到我,『那时候为什么从PHP转成Java?』,我想了很久,且撇开主观上的原因,当初业务重构使用java确实有很多可以说道的地方。 

    槽点1:哪有最好的语言,只有最合适的语言

    2017年的3月份,我所维护的业务,跑的是php,使用的是thinkphp3.2 框架。刚接手的时候,这个业务还是单机,还记得有同事笑道:『这台机厉害哈,单机一年能跑出200多万的流水来!』我当然是一笑置之。可是随着业务组扩展外部渠道,开始发展这个业务,我慢慢发现这样子的系统很难搞:难维护,难扩展,难自定义,不稳定。这样子的系统,每次改到支付功能,上线都是心虚的,就怕突然出现问题,影响用户体验。于是在一段煎熬的思索和过渡后,老大开始带着我进行重构。最开始的一套方案,是准备放弃原有的tp 框架,转而使用 yii2,但由于人手不够,老大亲自操刀,架起了一套 play1.4.3(业务端) + spring-mvc(后台管理) 的一套系统,所以,我也转到了java。

    我这里想说的是,一个项目选择啥语言,需要考虑团队的配置,不能上来就搞一套不切实际的东西,从实际出发,找到适合自己的语言。曾几何时,我也觉得php是世界上最好的语言,还没有之一,现在只觉得哪有最好的语言,只有最合适的语言。

    ......

    槽点2:面向对象编程,而不是面向数组编程

    也许你一定很想知道,如何才能完成从php 到 java 的转身呢?

    说实话,一开始的时候,确实很痛苦,基础薄弱就不说了,精神上还有压力,因为全世界都知道【你是写java的 php程序员】。举个特别糗的例子,刚刚写spring-mvc 的时候,不知道如何接收10多个参数,于是我很活该的使用了map, 我当时想啊,这不就是我们php 的 $_GET 和 $_POST 么【想当然害死人呀!】。可是写着写着我就发现不妥了,首先,别人并不知道你的map里面有啥子参数;然后,从map取出来的值不一定有值,如果是null,还要做逻辑判断,这样子代码又麻烦了。所以呀,虽然这个代码顺利上线了,也没发生过大的故障,但是我一直把这份代码当成我的【眼中钉,肉中刺】。后面我是知道了,其实用一个对象来接收这些参数,既优雅,有便于维护,可读性也好。

    下面,我把自己最恨的一段代码贴出来,告诫小伙伴们,【别这样子干啊】

       // 控制器 
      @RequestMapping(value = "/list", method = RequestMethod.GET) @ResponseBody public AjaxResponse getOrderList(@RequestParam Map<String, String> searchMap) { return orderService.getListsData(searchMap); }

      

     // 恶心的逻辑
      /**
         * 解析搜索关键词, 组装matches
         *
         * @param matches
         * @param searchKey
         * @param searchVal
         * @return
         */
        public Matches getMatchesBySearchMapEntry(Matches matches, String searchKey, String searchVal) {
            switch (searchKey) {
                
                case Properties.tradeType:
                    if (Integer.parseInt(searchVal) > 0) {
                        matches.eq(Columns.tradeType, searchVal);
                    }
                    break;
                case Properties.state:
                    int state = Integer.parseInt(searchVal);
                    if (state == 4) {
                        matches.match("complete_status", 1);    // 表示已完成
                    } else if (state == 3) {
                        matches.match("order_status", 0);   // 0 表示已下单
                    } else if (state == 1) {
                        matches.match("order_status", 1);   // 1 表示已支付
                    } else if (state == 2) {
                        matches.match("order_status", 2);   // 2 表示已退款
                    }
                    break;
                case Properties.channelId:
                    
                    List<Long> belongIds = accountService.getChannelIdBelongThisUser(HttpSessionUtils.getUseAccountId());
                    if (belongIds == null) {
                        if (GeneralUtil.isObjNotZero(searchVal)) {
                            matches.match("channel_id", searchVal); 
                        }
                    } else if (belongIds.size() > 0) {
                        Long id = Long.parseLong(searchVal);
                        if (belongIds.contains(id)) {
                            matches.match("channel_id", id); 
                        } else {
                            matches.match("channel_id", belongIds);
                        }
                    }
                    break;
                case Properties.cepingId:
                    if (GeneralUtil.isObjNotZero(searchVal)) {
                        
                        List<Long> cepingIds = scalePoolDao.findIdsByParentId(Long.parseLong(searchVal));
                        matches.match("ceping_id", cepingIds); 
    
                    }
                    break;
                case Properties.orderNo:
                    matches.match("order_no", searchVal);   
                    break;
                case Properties.openId:
                    String userKey = userDao.getUserKeyByOpenidAndUserType(searchVal, 1); 
                    matches.match("user_key", userKey);
                    break;
                case Properties.userKey:
                    matches.match("user_key", searchVal);
                    break;
                case Properties.createStartTime: // 下单时间
                    Date createStartTime = DateTimeHelper.timeFormatStringToDate(searchVal);
                    matches.gte("create_time", createStartTime);
                    break;
                case Properties.createEndTime:
                    Date createEndTime = DateTimeHelper.timeFormatStringToDate(searchVal);
                    matches.lte("create_time", createEndTime);
                    break;
                case Properties.payStartTime:    // 支付时间
                    Date payStartTime = DateTimeHelper.timeFormatStringToDate(searchVal);
                    matches.gte("pay_time", payStartTime);
                    break;
                case Properties.payEndTime:
                    Date payEndTime = DateTimeHelper.timeFormatStringToDate(searchVal);
                    matches.lte("pay_time", payEndTime);
                    break;
                case Properties.userType:
                    int userType = Integer.parseInt(searchVal);
                    if (userType > 0) {
                        matches.eq(Columns.userType, searchVal);
                    }
                    break;
                case Properties.buyType:
                    int buyType = Integer.valueOf(searchVal);
                    if (buyType > 0) {
                        if (buyType == BuyType.DEFAULT_COPY_ORDER.getCode()) { 
                            buyType = 0;
                        }
                        matches.eq(Columns.buyType, buyType);
                    }
    
                    break;
    
            }
            return matches;
        }
    

      

    我现在用又臭又长来形容,这样子的code 既不方便阅读,出问题了也不好排查。而且这个代码,我还是放在个循环中来拼接的,可读性之烂可想而知。唉,要是我如果有时间了,就把这段代码改了。

    其实呢,说了这么多,我就想说,包括我在内的部分 phper额,太过分依赖数组了。是啊,在php里面,没有啥是一个数组搞不定的,如果有,那就俩个。我走心看了下其它业务线的php代码,哎哟喂,好家伙。推送服务配置用数组,微信公众号配置用数组,接受请求用数组,传参用数组(个人最不喜欢的方式),好像数组少些,项目就不能正常运行了。

    我并不是说不该用数组,但是数组确实不好维护。当我们思绪乱的时候,你根本记不清这个数组中有哪些参数,你也可能想不起这个return的对象有哪些对象,特别是return json的时候,如果一个数组不存在,这时候返回了null,这样子返回的接口数据,对客户端的同学来说就是一种灾难。

    槽点3:一包不扫,何以扫天下

    除此之外,也是我最想吐槽的一点,就是php的命名空间和包管理。虽然php现在也有了composer,但是部分包载入时,还是需要做一下手动处理的,如果是一些小白的话,那久很尴尬了。相对于php呢,java就很成熟了,maven 一出,问题基本就解决了。而php的命名空间呢,我最不爽的一点是,明明一个包没关联上,项目居然还若无其事的走着,之前没觉得咋样,写java后就觉得,这样子特别不严谨,对于我这样的强迫症者来说,不能接受!

    还有就是,需要手动载入 扩展,关于这点,php做的不够好 

    槽点4:定时任务 

     此外呢,php有一点做的不够好的,定时任务!(且不说用swoole做定时任务哈,毕竟swoole还是需要点学习成本的呢!)

    之前我很少用php做定时任务,如果要做的话,就要依赖linux系统crontab,或者用swoole 了。

    但是在java里面,完全不是这样子的体验,在play 或者 spring-mvc ,完全就是一个job 就搞定了,哪里要这般麻烦!

    槽点 5:必不可少的单元测试

    然后呢,php 在单元测试方面比java 差挺多的。这里我不否认有idea 的功能,但是想要用phpunit 测试一个方法,我感觉千难万难,但是在java里,很容易就实现了!除此之外,包括我在内的部分phper,很少写单元测试,甚至有些压根就不知道这是咋回事!我觉得这是个可怕的现象,这样子的代码,连自己这关都没过,如何敢上线,如何能稳呢!基本上走过单元测试的代码,基本不存在啥语法错误,这就是妥妥的保障啊!

    槽点6:你debug都不用,就不要假装在搬砖了

    接下来, 包括我在内的部分phper 呢,很少去debug,有些甚至从来没这么搞过。在那段维护 thinkphp的时间了,我开始使用phpstrom的debug,说实话,代码质量,开发效率都有很大的提升!我实在不能再接受自己用 echo, var_dump 这样子去调试代码,这样子会让人觉得,这是个门外汉呢!

    槽点7:php是世界上最好的语言

    请放下这个想法,你会发现,无论是python,golang,java 都不比咱php差,你不知,只因你未接触!

    槽点8:php代码打包功能弱

    在写java前呢,每次遇到要复用的php代码呢,我都是直接copy,但是写java 一段时间后,我就觉得java 这方面比较好了,我可以通过maven 对共用的包进行打包,放到另一个项目中去,这样子既方便管理,又利于版本的迭代,省时省力!

    好了,就到这里吧,接下来还会有一篇吐槽java的。

  • 相关阅读:
    ETCD 添加节点报错 tocommit(2314438) is out of range [lastIndex(0)]. Was the raft log corrupted, truncated, or lost?
    如何删除docker镜像中已配置的volume
    kubeadm初始化集群
    kubeadm安装依赖镜像
    standard_init_linux.go:178: exec user process caused "no such file or directory"
    kubernetes支持local volume
    git http方式时保存密码
    分布式核心技术
    docker使用
    Python实用日期时间处理方法汇总
  • 原文地址:https://www.cnblogs.com/zeopean/p/8585633.html
Copyright © 2011-2022 走看看