JAVA 巧用继承降低需求变化时对现有代码的改动

来源:互联网 发布:nginx 市场占有量 编辑:程序博客网 时间:2024/06/05 17:51

前段时间接到包工头啊不项目经理分配了任务给我,对一系列设备写出对应的操作页面,页面效果如下这里写图片描述
点中想要操作的button,然后点击确定按钮,即可操作设备。
看到效果图我心里一沉,这种页面依赖了太多的可操作控件和对应的操作指令,日后必将成为大患。
但是没办法,这是工作。解决思路如下:

/**     * 存放指令信息     * @author BigYoung     *     */    class ActionInfo{        private String cmdName;//指令名        private String cmdValue;//指令值        public void setCmdName(String cmdName) {            this.cmdName = cmdName;        }        public void setCmdValue(String cmdValue) {            this.cmdValue = cmdValue;        }    }    ArrayList<ActionInfo> actionInfoList;//存放指令的数组    /**     * 点击事件监听器     * @author BigYoung     *     */    public interface EnsureButtonClickListener{        /**         *          * @param actionInfoList 后续处理需要的指令数组         */        public void afterButtonClick(List<ActionInfo> actionInfoList);    }

ActionInfo类代表指令,actionInfoList负责存放选中的指令,
点击button后调用ButtonClickListener.afterButtonClick执行后续操作.
我只能尽力减少需求变化对代码的影响,写下一个又一个的设备操作页面。
unfortunately,灾难还是来了。早上包工头面带笑容的找我谈话,然后神秘兮兮的对我说,从今天开始,我们改变设备的操作方式,选中想要操作的按钮后,立即执行操作指令。MLGB,这意味着我要重写所有的点击事件,更可怕的是,以后操作方式该回来的话,我又要重写所有的点击事件。
首先的解决方案是重写所有可操作view控件的点击事件,也就是加上如下代码:

if(mEnsureBtnListener!=null){    mActionInfoList.removeAll();    mActionInfoList.add(actionInfo);    mEnsureBtnListener.afterButtonClick(mActionInfoList);    }

虽然可以解决问题,不过,这代码写的也太垃圾了吧。如果以后操作方案改回来,那岂不是又要全部修改。
分析代码流程后发现,每次可操控设备被点击之后,都会进行一次mActionInfo.setCmdValue(“XX”)操作,我可以重写setCmdValue()方法,也就是将代码

if(mEnsureBtnListener!=null){    mActionInfoList.removeAll();    mActionInfoList.add(cmdInfo);    mEnsureBtnListener.afterButtonClick(mActionInfoList);    }

写在方法setCmdValue()后面,至于mActionInfoList对象可以通过构造方法传入。不过还是不妥,因为部分设备操作是需要多个指令才能执行,比如发出警报这类操作就需要灯光颜色指令和声音模式指令两个指令,以上代码只能令mActionInfoList保留一个指令对象。加入一些判断条件等待指令“到齐”再执行操作,又显得繁琐。
再次分析代码,发现单个指令也好,多个指令也好,最终都要保存在mActionInfoList数组里。忽然间想起了装饰者模式,也就是我可以写一个装饰类,装饰Arraylist类的add方法和addAll方法,代码如下:

 @Override    public boolean add(E e) {        clear();//清除现有指令        boolean result = super.add(e);//加入新指令        if (mEnsureBtnListener!= null) {//执行操作          mEnsureBtnListener.afterChooseDevice(mActionInfoList);        }        return result;    }    @Override    public boolean addAll(Collection<? extends E> c) {        clear();//清除现有指令        boolean result = super.addAll(c);//添加指令组        if (mEnsureBtnListener!= null) {      mEnsureBtnListener.afterChooseDevice(mActionInfoList);        }        return result;    }

不过,我需要的只是修饰add(),addAll()两个方法而已,继承更适合我。(部分代码省略)

public class JYDecorateArrayList<E> extends ArrayList<E> {    public boolean addNew(E e) {        clear();//清除现有指令        boolean result = super.add(e);//加入新指令        if (mEnsureBtnListener!= null) {//执行操作                            mEnsureBtnListener.afterChooseDevice(mActionInfoList);        }        return result;    }    public boolean addAllNew(Collection<? extends E> c) {        clear();//清除现有指令        boolean result = super.addAll(c);//添加指令组            if (mEnsureBtnListener!= null) {  mEnsureBtnListener.afterChooseDevice(mActionInfoList);        }        return result;    }}

大功告成,将代码改为mActionInfoList=new JYDecorateArrayList();在需要发送单个指令操作的地方调用mActionInfoList.addNew()方法,在需要发送指令数组操作的地方调用mActionInfoList.addAllNew()方法。就算以后需求发生变化,也就是点击按钮后不执行操作,那我只需重写addNew(),addaddAllNew()方法,令这两个方法不执行任何操作即可。
从这次经历中我学会了不要害怕改变,勇敢的去尝试。比如这次是我第一次继承java源码实现自己的需求,嘿嘿。各位看官,有用的话点个赞呗。

阅读全文
1 0