读书笔记----App研发录 第一章 重构

读书笔记—-App研发录 第一章 重构

感谢

  作为从ROM开发转行到应用开发的我来说,本书真是为我打开了一扇大门。正如作者所说,ROM开发不能算作应用开发,我们空有扎实的Java语言功底,却在应用开发处处碰壁。书籍概括了整个应用开发的流程,并且以一定的高度分析App竞品。这让我大大的收益,在此感谢作者的无私奉献。


第一章 重构

1.1 重构的过程


一,建立AndroidLib类库,将于业务无关的公用逻辑存放到库中.


com.infrastructure.activity
com.infrastructure.cache
com.infrastructure.net
com.infrastructure.ui
com.infrastructure.utils

  • activity包中包含 BaseActivity业务无关的的公用逻辑
  • net包中存放网络底层封装,AsyncTask.
  • cache包含数据缓存和图片处理相关
  • ui 自定义View
  • utils包含各种通用的工具类

二,将主项目中的类按照一定的规则划分,放入主项目的包中


  • activity :分模块继续化包
  • adapter
  • db :SQLite相关的逻辑
  • entity :实体
  • engine : 业务先关的类
  • ui : 自定义控件
  • utils : 公用方法
  • interfaces : 接口(intercace)
  • listener : 基于Listener的接口

  原则上是不出现嵌套类的形式,这个跟我做ROM开发时很不一样,在底层开发中的高内聚的特点,内部类很常用,所以不能完全否定内部类的用法。


如何建立依赖关系

* Android中建立AndroidLib

在菜单File -> New Module…选择Android Library

此时已经生成了目录以及相应的gradlew脚本

settings.gradle会成为include ':app', ':baselib'

最后在app的build.gradle中添加依赖项compile project(path: ':baselib')

完成


1.2 为Activity定义新的生命周期

  四大组件的生命周期是由AMS通过handler机制去hook周期函数。重新定义生命周期并不是改变这一生命周期的调用函数或顺序。而是将生命周期中的工作模块化(方法化)。

示例

public abstract class BaseActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initVariables();
        initView(savedInstanceState);
        loadData();
    }

    protected abstract void initVariables();

    protected abstract void initView(Bundle savedInstanceState);

    protected abstract void loadData();


}

  此时集成父类的子类就可以不重写Activity的生命周期函数onCreate(),保证了更细化的单一职责的设计模式。在编写代码的过程中,向”父类层次抽象“能有效的提高代码的可读性,降低冗余。

public class AppBaseActivity extends BaseActivity {
    @Override
    protected void initVariables() {

    }

    @Override
    protected void initView(Bundle savedInstanceState) {

    }

    @Override
    protected void loadData() {

    }
}

1.3 统一事件编程模型(体现面向对象的思想)

        /* 面向对象的Click写法 */
        btnLogin = (Button) findViewById(R.id.btn_Login);
        btnLogin.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        //避免代码臃肿
                        gotoLoginActivity();
                    }
                }
        );

1.4 实体化编程

AndroidStudio导入GSON,只需要在项目设置中添加Lib依赖项就可以了
compile 'com.google.code.gson:gson:2.7'

Gson gson = new Gson();
        WeatherEntity weatherEntity = gson.fromJson(content, WeatherEntity.class);
        WeatherInfo weatherInfo = weatherEntity.getWeatherInfo();
        if (weatherInfo != null) {
            tvCity.setText(weatherInfo.getCity());
            tvCityId.setText(weatherInfo.getCityId);
        } 

在组件之中传递实体需要用到序列化,实现Serializable接口或者Parcel接口

intent.putExtra("String", entity);//发送
getIntent().getSerializableExtra("String");//接受

1.5 Adapter模板

  利用实体化编程以及面向对象的编程的思想,将ListView的显示分装,作为普通的View去显示,而点击事件的处理等,操作,应该放到ListView的外部。符合单一职责

1.6 类型安全转换函数

提供一个工具函数,转换失败就返回默认值
convertToInt

    public final static int convertToInt(Object value, int defaultValue) {
        if (value == null || "".equals(value.toString().trim())) {
            return defaultValue;
        }
        try {
            return Integer.valueOf(value.toString());
        } catch (NumberFormatException e) {
            try {
                return Double.valueOf(value.toString()).intValue();
            } catch (NumberFormatException e1) {
                return defaultValue;
            }
        }
    }

substring()函数的越界问题

    String convertStr = "T";
    String needStr = "";
    if (convertStr.length() > 1) {
        needStr = convertStr.substring(1, 2);
    }

重构手法简介

参考自:Android开发进阶,从小工到专家 ————何红辉

重构的原因

优化代码

  无论什么时候,代码的规范性,合理性是程序员入职的首先要求,作用自然不言而喻。而现实是代码一直在演化,在改进。而改进的过程就可以成为重构的过程。而改进的过程是需要随时进行的。

常见重构手法

  1. 提取子函数
      我们在第二节的时候所用到的手法的第一步,就是将代码符合单一职责,提取并封装成一个个单独方法。

  2. 上移函数,字段到父类
      这是一个继承原则的最好体现,将子类公用的代码上移到父类。改变父类就改变了所有子类。

  3. 下移函数,字段到子类
      这个过程并不是与上面的相反,而是提取出差异,新建父类继承共性添加差异,组成新的共性父类。

  4. 封装固定的调用逻辑
     这个很好理解,类似于链式启动,将固定的逻辑封装为方法。

  5. 泛型编程
     泛型编程适用于操作逻辑一样,但是具体的操作对象不一样。

  6. 避免使用过多参数(实体化编程)
     总而言之,实体化编程更容易让人理解,同样更容易操作,上边1.4节就是最好的体现

  7. 转移函数
     转移函数解决了类型之间的过度耦合问题,类A频繁的调用类B中的一个或一组方法,而类B调用此方法不频繁。这时候需要将B中的方法转移到A中。

  8. 将类型码转换为状态模式
     基本原则多态的简单应用,这涉及到一个java的涉及模式状态模式(对象行为型)。简单的介绍:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
    适用性:
     1,一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。
     2,代码中包含大量与对象状态有关的条件语句:一个操作中含有庞大的多分支的条件(if else(或switch case)语句,且这些分支依赖于该对象的状态。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。

  9. 什么也不做的对象—NullObject
     空指针异常(NullPointException)是非常常见的异常,我们为了避免空指针异常,通常在使用这个某个对象的时候要进行判空判断(在我的一个项目中,一个线程新New出来对象,传入另一个线程执行却报了空指针,复现率很低。最终原因是因为Java虚拟机允许CPU乱序执行,导致线程中对象可能还未创建成功,已经换了线程。最终引入volatile或者单例才能解决。)所以,空指针是防不胜防的。如何良好的处理空指针是代码重构的很重要的一环。
     实现方式:创建一个空的对象实现功能接口,在获取这个的时候,判断是否为空,如果为空,则返回空对象的实例。1.6 节的思想也是类似的。

总结

 其实我们对代码的重构,本质上遵循了六大设计原则。这是编码的根本准则,只有遵循这些准则,才会让代码避免恶化的脚步。拥有更好的扩展性,易读性和便于维护。

作者 [@PirateBrook]
2016 年 10月 20日

你可能感兴趣的:(读书笔记)