admin 管理员组

文章数量: 1087675

代理模式实现优雅地修改同事的代码

前言

        在开发过程中,很多时候我们是需要在同事代码的基础上进行开发的,同时的代码你敢动吗?你开始以为只是一个小问题,你尝试着修复这个BUG,然而修复之后,你发现其他地方不能用了,因为你的修复触发了更多的BUG......我相信每个3年以上工龄的老鸟都或多或少遇见过这种问题。有没有一种方式可以优雅的修改同事的代码呢?下文我就给大家介绍一种优雅修改同事代码的思路。

分析

        修改同事的代码一般是产品经理提出的需求,虽然这种需求林林总总多种多样,但归结起来无非是这三类:

        类别1:非侵入式修改前同事代码,对前同事的代码做一些增强。

        类别2:侵入式修改前同事代码,对前同事的代码做逻辑上的改动。

        类别3:升级同事代码,但是要求老版本依然可用,甚至还可能有新旧版本切换的需求。

        非侵入式代码,本质是对同事的代码做一些增强处理,这挺着熟悉不?像不像注解的功能?注解就是用代理模式实现的,我们能否常使用代理模式的思路解决该问题?

案例

        产品经理看完《狂飙》之后,想开发一个吃鱼的需求。同事阿飞是这样设计的:

        产品经理想吃鱼,老板也想吃鱼,我们不能只写一个吃鱼的过程,而应该对过程抽象,面向接口编程,这样对修改关闭、对扩展开放才符合开发原则嘛。

        1、阿飞设计的抽象接口:

public interface EatService {// 吃的方法void eat(String name);
}

        2、阿飞设计的具体实现

public class EatServiceImpl implements EatService{@Overridepublic void eat(String name) {System.out.println(name+",告诉老默,我想吃鱼了...");}
}

        3、阿飞的测试类

public class EatTest {public static void main(String[] args) {EatService service = new EatServiceImpl();service.eat("小虎");}
}

        4、运行结果如下:

 

        产品经理看过阿飞的设计,觉得不太满意,大家都是文明人,应该讲卫生,吃鱼之前应该先洗手,怎么能直接就吃鱼呢?然而这个时候阿飞已经调去数据组了,只能由新同事小李重新修改代码:吃鱼之前要先洗手。

        小李是一个老鸟,他就是因为在前公司改同事代码搞出一堆问题所以才离职的,于是他就下定决心要搞一种方式去避免这样的问题,他接到代码是这样想的:我要做一个代理,对小李的代码进行前置增强,即可完成产品的需求。

public class EatProxyServiceImpl implements EatService {private EatServiceImpl impl = new EatServiceImpl();@Overridepublic void eat(String name) {boolean flag = true;boolean isWashHands = isWashHands(flag);if (isWashHands) {System.out.println("洗完手了,可以准备吃饭了...");} else {System.out.println("未洗手,陈书婷不让吃东西...");return;}impl.eat(name);}// 是否洗手private boolean isWashHands(boolean flag) {return flag;}
}

         测试代码:

public class EatTest {public static void main(String[] args) {EatService service = new EatProxyServiceImpl();service.eat("小虎");}
}

        注意:这里的实际调用由原来的EatServiceImpl转而改成EatProxyServiceImpl了。

        测试结果:

        产品把实现好的需求给老板看,老板说“客户什么档次的,人家吃的是海鲜,人家不吃鱼。”

        产品黑着脸继续找到小李:“小李,老板说客户吃海鲜,不吃鱼,马上要改好,明天给客户演示。”

        小李推三阻四:“产品,不好吧,我都没工时了,需求改来改去很复杂的。改阿飞代码要1天,调试要1天,测试要1天......”

        因为时间紧,产品也没多磨叽,直接给小李加了8个工时,“干不干?不干我找别人去”。

        充值到账,小李马上开始改代码:

public class EatProxyServiceImpl implements EatService {private EatServiceImpl impl = new EatServiceImpl();@Overridepublic void eat(String name) {System.out.println(name+",告诉老默,吃鱼档次太低,我想吃海鲜...");}// 是否洗手private boolean isWashHands(boolean flag) {return flag;}public EatService getEatServiceImpl() {return impl;}
}

         测试结果如下:

        小李只用了1个小时就搞完了,含泪赚了7个工时。

        第二天给客户演示,客户问产品:“马总喜欢吃海鲜,但是余总喜欢吃鱼,不知道你们这能不能吃鱼?”

        客户都提需求了,产品能说不行吗?行,怎么不行啊?1小时改好。

        产品过来找小李,“小李,你怎么上班摸鱼啊?”

        小李关掉NBA网页,“有事说事,别吓唬朕,你行你改?”

        产品赶紧过来给小李 揉肩,“李哥,哪个客户那边余总说还要吃鱼。”

        小李翻脸就骂:“产品我**你大爷,你昨天从吃鱼改吃海鲜,今天又要吃鱼,你耍猴呢?”

        产品两手一摊:“客户需求,我有什么办法,1个小时,能不能做?不能做我把你上班看X片的录像发给老板。”

        小李一下子软了下来,“能做,30分钟改好,但是你不许留底版。”

        产品:“一言为定。”

public class EatProxyServiceImpl implements EatService {private EatServiceImpl impl = new EatServiceImpl();@Overridepublic void eat(String name) {System.out.println(name+",告诉老默,吃鱼档次太低,我想吃...");}// 是否洗手private boolean isWashHands(boolean flag) {return flag;}public EatService getEatServiceImpl() {return impl;}
}

        小李用5分钟加了个getEatServiceImpl()方法,可以调用该方法获取阿飞之前代码的实例吃鱼,也可以用小李新写的方法吃海鲜,又含泪赚了55分钟的工时。

        哎,摸鱼人的快乐,你们不懂得。

本文标签: 代理模式实现优雅地修改同事的代码