Android项目重构之路:实现篇(二)

2016/02/21 18:48
阅读数 181

核心层的逻辑

核心层处于接口层和界面层之间,向下调用Api,向上提供Action,它的核心任务就是处理复杂的业务逻辑。先看看我对Action的定义:

public interface AppAction {
   // 发送手机验证码
   public void sendSmsCode(String phoneNum, ActionCallbackListener<Void> listener);
   // 注册
   public void register(String phoneNum, String code, String password, ActionCallbackListener<Void> listener);
   // 登录
   public void login(String loginName, String password, ActionCallbackListener<Void> listener);
   // 按分页获取券列表
   public void listCoupon(int currentPage, ActionCallbackListener<List<CouponBO>> listener); }

首先,和Api接口对比就会发现,参数并不一致。登录并没有iemi和loginOS的参数,获取券列表的参数里也少了pageSize。这是因为,这几个参数,跟界面其实并没有直接关系。Action只要定义好跟界面相关的就可以了,其他需要的参数,在具体实现时再去获取。
另外,大部分action的处理都是异步的,因此,添加了回调监听器ActionCallbackListener,回调监听器的泛型则是返回的对象数据类型,例如获取券列表,返回的数据类型就是List ,没有对象数据时则为Void。回调监听器只定义了成功和失败的方法,如下:

public interface ActionCallbackListener<T> {
   /**     * 成功时调用     *     * @param data 返回的数据     */
   public void onSuccess(T data);
   
   /**     * 失败时调用     *     * @param errorEvemt 错误码     * @param message    错误信息     */
   public void onFailure(String errorEvent, String message); }

接下来再看看Action的实现。首先,要获取imei,那就需要传入一个Context;另外,还需要loginOS和pageSize,这定义为常量就可以了;还有,要调用接口层,所以还需要Api实例。而接口的实现分为两步,第一步做参数检查,第二步用异步任务调用Api。具体实现如下:

public class AppActionImpl implements AppAction {
   private final static int LOGIN_OS = 1; // 表示Android
   private final static int PAGE_SIZE = 20; // 默认每页20条

   private Context context;
   private Api api;
   
   public AppActionImpl(Context context) {
       this.context = context;
       this.api = new ApiImpl();    }
       
   @Override
   public void sendSmsCode(final String phoneNum, final ActionCallbackListener<Void> listener) {
       // 参数为空检查
       if (TextUtils.isEmpty(phoneNum)) {
           if (listener != null) {                listener.onFailure(ErrorEvent.PARAM_NULL, "手机号为空");            }
           return;        }
       // 参数合法性检查
       Pattern pattern = Pattern.compile("1\\d{10}");        Matcher matcher = pattern.matcher(phoneNum);
       if (!matcher.matches()) {
           if (listener != null) {                listener.onFailure(ErrorEvent.PARAM_ILLEGAL, "手机号不正确");            }
           return;        }
           
       // 请求Api
       new AsyncTask<Void, Void, ApiResponse<Void>>() {
           @Override
           protected ApiResponse<Void> doInBackground(Void... voids) {
               return api.sendSmsCode4Register(phoneNum);            }
               
           @Override
           protected void onPostExecute(ApiResponse<Void> response) {
               if (listener != null && response != null) {
                   if (response.isSuccess()) {                        listener.onSuccess(null);                    } else {                        listener.onFailure(response.getEvent(), response.getMsg());                    }                }            }        }.execute();    }
                   
   @Override
   public void register(final String phoneNum, final String code, final String password, final ActionCallbackListener<Void> listener) {
       // 参数为空检查
       if (TextUtils.isEmpty(phoneNum)) {
           if (listener != null) {                listener.onFailure(ErrorEvent.PARAM_NULL, "手机号为空");            }
           return;        }
       if (TextUtils.isEmpty(code)) {
           if (listener != null) {                listener.onFailure(ErrorEvent.PARAM_NULL, "验证码为空");            }
           return;        }
       if (TextUtils.isEmpty(password)) {
           if (listener != null) {                listener.onFailure(ErrorEvent.PARAM_NULL, "密码为空");            }
           return;        }
           
       // 参数合法性检查
       Pattern pattern = Pattern.compile("1\\d{10}");        Matcher matcher = pattern.matcher(phoneNum);
       if (!matcher.matches()) {
           if (listener != null) {                listener.onFailure(ErrorEvent.PARAM_ILLEGAL, "手机号不正确");            }
           return;        }
       
       // TODO 长度检查,密码有效性检查等

       // 请求Api
       
new AsyncTask<Void, Void, ApiResponse<Void>>() {
           @Override
           protected ApiResponse<Void> doInBackground(Void... voids) {
               return api.registerByPhone(phoneNum, code, password);            }
               
           @Override
           protected void onPostExecute(ApiResponse<Void> response) {
               if (listener != null && response != null) {
                   if (response.isSuccess()) {                        listener.onSuccess(null);                    } else {                        listener.onFailure(response.getEvent(), response.getMsg());                    }                }            }        }.execute();    }
                   
   @Override
   public void login(final String loginName, final String password, final ActionCallbackListener<Void> listener) {
       // 参数为空检查
       if (TextUtils.isEmpty(loginName)) {
           if (listener != null) {                listener.onFailure(ErrorEvent.PARAM_NULL, "登录名为空");            }
           return;        }
       if (TextUtils.isEmpty(password)) {
           if (listener != null) {                listener.onFailure(ErrorEvent.PARAM_NULL, "密码为空");            }
           return;        }
           
       // TODO 长度检查,密码有效性检查等

       // 请求Api
       
new AsyncTask<Void, Void, ApiResponse<Void>>() {
           @Override
           protected ApiResponse<Void> doInBackground(Void... voids) {                TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);                String imei = telephonyManager.getDeviceId();
               return api.loginByApp(loginName, password, imei, LOGIN_OS);            }
               
           @Override
           protected void onPostExecute(ApiResponse<Void> response) {
               if (listener != null && response != null) {
                   if (response.isSuccess()) {                        listener.onSuccess(null);                    } else {                        listener.onFailure(response.getEvent(), response.getMsg());                    }                }            }        }.execute();    }
   
   @Override
   public void listCoupon(final int currentPage, final ActionCallbackListener<List<CouponBO>> listener) {
       // 参数检查
       if (currentPage < 0) {
           if (listener != null) {                listener.onFailure(ErrorEvent.PARAM_ILLEGAL, "当前页数小于零");            }        }
       
       // TODO 添加缓存

       // 请求Api
       
new AsyncTask<Void, Void, ApiResponse<List<CouponBO>>>() {
           @Override
           protected ApiResponse<List<CouponBO>> doInBackground(Void... voids) {
               return api.listNewCoupon(currentPage, PAGE_SIZE);            }
               
           @Override
           protected void onPostExecute(ApiResponse<List<CouponBO>> response) {
               if (listener != null && response != null) {
                   if (response.isSuccess()) {                        listener.onSuccess(response.getObjList());                    } else {                        listener.onFailure(response.getEvent(), response.getMsg());                    }                }            }        }.execute();    } }

简单的实现代码就是这样,其实,这还有很多地方可以优化,比如,将参数为空的检查、手机号有效性的检查、数字型范围的检查等等,都可以抽成独立的方法,从而减少重复代码的编写。异步任务里的代码也一样,都是可以通过重构优化的。另外,需要扩展时,比如添加缓存,那就在调用Api之前处理。
核心层的逻辑就是这样了。最后就到界面层了。

本文分享自微信公众号 - Keegan小钢(keeganlee_me)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部