工作也已经四年多了,在今年才有了“好记性不如烂笔头”的觉悟,以后会慢慢将工作中的感悟以文档的形式记录下来。
ps:以下为个人感悟,持续更新… 如有错误,欢迎指正,谢谢!
被多数人忽略的 final 关键字
在日常写代码过程中,包括我,常常会忽略使用 final关键字,使得一个类可以被随意继承、一个方法可以被子类随意重写、一个变量可以被随意赋值,这实际上是不安全的,对于一个不熟悉你代码的人,可能你写的不应该有子类、不允许被重写等等。
不知道大家有没有发现kotlin声明变量有两种方式 var val,并且kotlin中的类默认是不允许被继承的,相当于java中final修饰的类,我想这可能就是为了防止这一现象吧。
所以我们应该尽可能使用final,有需要再进行修改。
权限修饰符
我们在日常开发过程中,可能会有这么一种情况,封装了一个功能类,为这个功能类单独提供了一个统一的单独对外调用的类,不希望有人直接去调用功能类,我们这时候就需要合理的使用权限修饰符,将功能类设置为非public的,对外的类放在同包下,使用public。
也是为了增强项目的安全性、稳定性及贯彻迪米特原则,应该合理地使用权限修饰符,在写代码的时候,尽量用最严格的权限,如果确实有需要,再进行权限扩大,如:private -> 默认 -> protected -> public 。
修饰符 | 本类中 | 子类中 | 同包 | 非同包 |
---|---|---|---|---|
public | 可以 | 可以 | 可以 | 可以 |
protected | 可以 | 可以 | 可以 | 不可以 |
默认 | 可以 | 同包子类可以 | 可以 | 不可以 |
private | 可以 | 不可以 | 不可以 | 不可以 |
门面模式
在开发过程中,我们都会使用第三方框架,如:网络、图片、json等。
我们不应该在项目代码中直接地去调用sdk中的代码,会导致耦合严重,后期维护困难。举个栗子:
- glide 3.x -> glide 4.x 框架调用方式变化比较大,如果一开始项目中大量直接使用了 3.8 版本的 glide.with().load().error().into(),现在升级为4.x岂不是所有地方都要改成 glide.with().load().apply(new Options().error()).into(),无疑是维护成本是巨大的。
- 比如项目中开始用的glide,现在因为某种原因要换成Picasso;或者开始用的FastJson,现在要换成Gson;项目中所有地方是不是都要改?耗时耗力,还容易出问题。
为此,我们应该为这些sdk去封装一层门面,我们的业务代码不要直接去调用sdk,而是调用我们的门面方法,如:
ImageFacade.java
JsonFacade.java
单一使用门面模式的问题
上面讲了使用门面模式的好处,有没有缺点呢?答案是有的,违法了开闭原则,因为我们一旦替换框架,我们封装类的内部就相当于了重构,以JsonFacade.java 为例(大家知道意思就好):
public JsonFacade{
public <T> T toObject(String jsonString, Class<T> cls) {
//return FastJson实现
Gson实现
}
}
为此,我们应该使用代理模式,来规避这种问题,以静态代理为例:
public interface IJsonParse{
<T> T toObject(String jsonString, Class<T> cls);
}
public class FastJsonFacade implements IJsonParse{
@Override
public <T> T toObject(String jsonString, Class<T> cls) {
//FastJson实现
return null;
}
}
public class GsonFacade implements IJsonParse{
@Override
public <T> T toObject(String jsonString, Class<T> cls) {
//Gson实现
return null;
}
}
public class JsonProxy implements IJsonParse {
private static JsonProxy mInstance = new JsonProxy();
private static IJsonParse mIJsonParse;
public static JsonProxy getInstance() {
return mInstance;
}
public static void init(IJsonParse iJsonParse) {
mIJsonParse = iJsonParse;
}
@Override
public <T> T toObject(String jsonString, Class<T> cls) {
return mIJsonParse.toObject(jsonString, cls);
}
}
我们只需要在Application中直接init(FastJsonFacade/GsonFacade)一行代码实现切换。