写代码仅仅是“写”代码吗?

写代码仅仅是“写”代码吗?

转载请注明出处 http://blog.csdn.net/wzlyd1/article/details/52635241

前言

最近一直忙于新功能的开发,一直没有时间写博客,之前说的坚持写博客又被中断了,我的错。
话说在今年三月份我被调到了一个新的部门,说新的 也不是很对,因为这个部门是我们公司最老的部门了,因为缺开发,所以把我调了过来。
看到标题,很多人都会不假思索的在心里默道,肯定不是”写”代码,因为还有逻辑等巴拉巴拉,但是又说不出个所以然,那么今天我们就来扯一扯代码究竟该怎么写。

变量命名

m开头

很多博客在讲到变量命名的时候都会提到驼峰命名法,帕斯卡命名法,对于我个人而言我是比较喜欢这两种命名方式的,整齐,画一,但是我更推荐谷歌源码的命名方式,成员变量在前面以m开头(member) 以和局部变量区分开来,因为当你代码量增加而局部变量和成员变量长的一样的时候,这简直就是一场灾难。

至于还有一些见名知意等规则不再赘述,博客一搜一大把。

下划线方式命名

之所以把这中命名方式拎出来是因为好多博客,或者很多初学者会这么写,可能是因为写博客,主要是为了传授一些知识,在细节方面没有考虑很多,新手呢,主要是因为为了方便,我布局里写完,直接复制过来,省事,但是如果这样,问题就出来了,也许代码少的时候没有问题,代码量多了,就惨不忍睹了,上图感受一下
这里写图片描述
单独看,你觉得可能还行,因为我只截取了一半代码,想像一下100多行代码(当然,如果你发现某个文件的变量定义特别多,你要注意了,可能代码耦合太严重了,赶紧拆分)都是这么定义的,你看起来会舒服?

先说这几个变量命名的优点吧。
1 基本做到了见名知义,在看到变量名时至少我知道这是做什么的。

2 好像没啥优点了,全是槽点。。。。

说说这几个变量命名的槽点
1,没有以m开头,实际上在代码里,有的局部变量名字和成员变量名一样,这样就容易导致混淆,在维护代码时候一个不小心,你懂得。

2 变量命名混乱,估计是好多人接手过这个代码,就目前看到的,有下划线命名方式,有驼峰命名方式,还有谷歌源码似的命名方式,乱成一锅粥,长短不一,犬牙交错。

3,常量的命名 ,命名方式还算是正确,但是混到了非常量里面去,这就像一朵红色的鲜花硬生生的插进了牛粪里,你再漂亮,也么人睬你。

4 ,我觉的不好的地方 ,就是一个声明下定义N多变量,虽然这个有点吹毛求呲,但是这个我确实不推崇,这也是为了我讲一个特别重要的原则的前提条件,那就是代码分块

代码分块

在说之前,我强烈建议所有局部变量用m开头的驼峰命名法,不要用下划线方式,那个用来定义布局文件里的id好了,难道你没有觉得下划线命名方式读起来很累,而且还一顿一顿的?

为什么要代码分块?

在看完上述栗子之后,你有没有发现,虽然代码每个意思我都知道,但是我还是不知道这代码是干啥的,对该页面功能没有一个完整的认知。这就需要代码分块了
说起来可能你不懂,上图感受
这里写图片描述
看到这个,即使我没有看变量,我也对页面有了一个整体的认知,在需要修改某块功能的时候,我就可以很快的定位到我需要修改的地方,并且顺藤摸瓜,找到该功能所有的变量,很快的做出修改,而不是先通过布局,然后再全局搜索变量求修改,相同的功能,一会变量在第10行一会又跑到八竿子打不着的第30行。

具体说来,代码分块就是

相同功能的模块下,view的变量定义在一起,数据变量定义在一起,不要混定义,一会view 一会数据

代码的命名最好顺序和你布局文件一致,比如一个button在左上角,那你就第一个命名button,一个textView在最底部,那么你就最后命名该view好了,不要把他扔在第一个,这样的话,我们所看即所得,当我修改了第一个,我会很自然的顺藤摸瓜向下找第二个,而不是在代码块里有开始了上蹦下跳。

哦,对了,我们还说到过常量的定义,关于常量的定义,我建议扔在类的最开始,因为这些是我们不做修改的,几乎没啥逻辑可言.同样,上图感受

这里写图片描述

是不是简洁明了?

代码里我们应该注意什么

说完变量的命名,我们看看平时我们在写逻辑的时候需要注意什么。

很多人会将代码出bug率高归咎于逻辑性不好,事实上还有很大一个原因被忽略是因为代码习惯。
举个栗子:
页面数据之间的传递我们通常用intent或者bundle ,(个人推荐bundle,更加容易管理),很多人会这么写
这里写图片描述
然后在接收的页面写 intent.get(“ctype”,”11”)。好,写完了,上线,没错,自己觉得很完美,但是,真的很完美么,假设以后Pm让增加一个功能,那么需要多传一个参数,好,你得一个个找哪个页面有向这个页面传参,找到,然后多写一句,intent.putExtra(xxx,xxx),然后在自己的页面再写一句intent.get(xxx,xxx),结束完工,感觉还不错?
那是因为页面还少

当10+个页面的时候,你就崩溃去吧,一个个找,然后一个个写,而且,万一有一个没有找到,上线就是bug,等着卷铺盖走人吧。(还有一些常量,千万要定义好,这个栗子中11是什么鬼你知道么?
说到底,这是因为代码没有收口的地方。

事实上,我们需要哪些参数,只要在我们需要的页面全部定义好,方法也定义好,别的页面需要传的时候直接调用该方法就好了,而你一旦增加参数,只需要在该方法里增加即可,其他地方用找吗,不用,因为会自动报错,快速定位修改,简单很多。
举个简单的栗子
secondActivity是我们需要跳转的页面
mainActivity是主页面,我们跳转secondActivity需要三个参数
代码如下

public class SecondActivity extends Activity {
    public static final String EXTRA_NAME_ID = "name";
    public static final String EXTRA_SEX_ID = "sex";
    public static final String EXTRA_AGE_ID = "age";


    /**
     * 我们需要的参数
     * @param name
     * @param sex
     * @param age
     * @return
     */

    public static Bundle getBundle(String name, String sex, String age){
        Bundle bundle = new Bundle();
        bundle.putString(EXTRA_NAME_ID,name);
        bundle.putString(EXTRA_SEX_ID,sex);
        bundle.putString(EXTRA_AGE_ID,age);
        return bundle;
    }



}
public class JumpUtils {

    public static  void startActivity(Activity fromActivity, Class<?> toActivity, Bundle bundle){

        Intent intent = new Intent();
        intent.putExtras(bundle);
        intent.setClass(fromActivity,toActivity);
        fromActivity.startActivity(intent);

    }
}

mainActivity 代码

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();


        //假设我们在这里需要跳转页面
        JumpUtils.startActivity(this, SecondActivity.class, SecondActivity.getBundle("lyd", "男", "24"));
    }

这样,我们就完成了所有的操作,假如PM要求新增参数,我们只需要在secondActivity增加就好了,其他什么都不用管,会自动报错,而且常量我们也不能直接写String,一是容易写错,二是不方便管理,没有收口。

布局的嵌套

关于布局的嵌套,不想说很多,只想说一点,ViewGroup里只有一个子Child的话那么有99%可能性能将外层的viewGroup干掉,这一点要时刻记着
举个栗子

这里写图片描述

这种的一眼就可以看出来,有的是一眼看不出来的,比如外层有一个relativlayout ,里层是一个linearLayout,在linearlayout里面有10+个子view,这种也是可以把外层的relativlayout 干掉的,没啥用。

分支语句

为了少写一点内容,这里把事件的回调也写到这里,因为问题是一样的.

什么是分支语句,大家都知道,if-else 和switch,但是有些人写代码就不注意,在分支语句里写大量的代码,比如:
这里写图片描述

不清楚这么写的意义在哪里,当分支很多的时候。简直就是一场灾难!

类似的还有在Onclick事件里,在网络请求的接口回调OnSuccess里,或者OnError里面
说起if-else语句,恐怕大多数人会有这么一个习惯,就是

if(a)
{return true}
else{
return false};

这种的直接return a 好了。。。
可能大家都会说,这个我当然知道了, 这么简单,但是实际运用中,还是出现了类似的情况
这里写图片描述

这尼玛~~~
通常情况下,如果if-else语句里只有一行语句,直接用三目运算符好了
比如上面,我会这么写

int drawableId = b?R.drawable.selector_order_submit_orange:R.drawable.selector_order_primary_disable;
tv_hotel_order_booking.setBackground(drawableId );

搞定,还少些了一个if-else语句.

分支语句里尽量少写语句,类似的还有网络回调,你只需要告诉我是干什么的就醒了,至于其中细节,我并不关心,但是我相信有很多人犯如下错误:
这里写图片描述

有哪些错误呢

1 —-分支语句里写了太多逻辑 2—–暴露了太多逻辑细节,后续维护蛋疼 3—–命名 4—–常量

假设在网络成功回调之后,我们需要做三件事情,渲染view,计算时间,跳转页面,那么我只需要定义三个方法就好了,refreshView()
,caculateTime()
,goToSecondActivity(),至于我怎么渲染,怎么计算,跳转页面需要传哪些参数我并不关心,你只要告诉我做了哪些事,完成什么功能就ok了,暴露细节,只会让代码看起来繁琐,维护困难。

互斥条件写到一起

估计很多人没有看懂这个意思,但是肯定遇到一些类似下面的bug
这里写图片描述
这里写图片描述

也就是莫名其妙的出来不该出来的界面
WTF!如果你代码写的很零散的话,还不好改,因为你根本不知道某view在何时才展现出来。

这种问题很常见,但是不一定好解决,但是很容易根除,是根除!

关于这种显示互斥的东西,比如上图,查询房间的时候是肯定不可能展现不可预定的,显示结果布局的时候肯定是也不可能展现查询失败界面的,这些都是互斥展示的,一个出现另一个肯定不会出现。

解决很简单,上图

这里写图片描述

如果一个出现,另一个肯定不出现的话,我就封装好,强制他隐藏,管他之前什么状态,这样绝对就不会出现上图的问题。

后记

其实还有很多需要注意的地方没有说,比如,不要在构造方法里传数据(除了必要参数),有些人为了方便,会在构造参数里传数据,而不是给外部提供一个接口,这样,我得需要得到该数据的时候才能初始化该控件,而不能在一开始初始化,比如在构造参数里传了接口返回的数据,那我只能在onsuccess里初始化,这就造成了隐患,别人一旦用我的控件,我还没有初始化,那就空指针了······

代码要多用空格回车分割

现在简书这么受欢迎,你会发现,里面的文章段落不是传统的段落,段落段落之间空间很大,而且每行的字数基本很少,读起来很舒服,同样,写代码也是这样.

可能会有很多人对这些规则不屑一顾,认为编程,重要的是知识储备量,但是我觉得这是大错特错了,如果你现在学习深奥的知识很吃力,我建议你把这篇文章好好读一下,很有帮助。对你的逻辑也会很有帮助,会让你逻辑更加缜密,不容易出错

如果你不信,我可以告诉你,我来这个部门之前,bugly一屏上10个条目,有2/3是空指针,如今,已经很难找了,这就是规范的力量,你说我有对他们的逻辑进行培训吗,并没有,只是从最基础做起,将简单做到极致,就是不简单。

最后,还是要说一下,养成一个好习惯,一定要养个好习惯,可能我说的这些建议不一定对,所以一定要汲取百家所长,增强自己的能力。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值