资源描述:
《了解Java8重构传统设计模式》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
了解Java8重构传统设计模式java8中提供的很多新特性可以用来重构传统设计模式中的写法,希望对您的学习有所帮助。假设我们现在要保存订单,OrderService接口定义要做什么,而NoSqlSaveOrderStragegy以及MySqlSaveOrderStrategy则提供了二种策略,分别是保存到nosql数据库,以及传统的mysql关系型数据库,最后在OrderServiceExecutor中通过构造函数注入最终要使用的策略。java8中提供的很多新特性可以用来重构传统设计模式中的写法,下面是一些示例:1.策略模式上图是策略模式的类图,假设我们现在要保存订单,OrderService接口定义要做什么,而NoSqlSaveOrderStragegy以及MySqlSaveOrderStrategy则提供了二种策略,分别是保存到nosql数据库,以及传统的mysql关系型数据库,最后在OrderServiceExecutor中通过构造函数注入最终要使用的策略。
1传统写法,这个场景至少得4个类,代码如下:OrderService接口:publicinterfaceOrderService{voidsaveOrder(StringorderNo);}Mysql策略实现:publicclassMySqlSaveOrderStrategyimplementsOrderService{@OverridepublicvoidsaveOrder(StringorderNo){System.out.println("order:"+orderNo+"savetomysql");}}Nosql策略实现:publicclassNoSqlSaveOrderStrategyimplementsOrderService{@Override
2publicvoidsaveOrder(StringorderNo){System.out.println("order:"+orderNo+"savetonosql");}}使用策略的辅助"容器":publicclassOrderServiceExecutor{privatefinalOrderServiceservice;publicOrderServiceExecutor(OrderServiceservice){this.service=service;}publicvoidsave(StringorderNo){this.service.saveOrder(orderNo);}}运行测试类:
3publicclassOrderServiceTest{publicstaticvoidmain(String[]args){OrderServiceExecutorexecutor1=newOrderServiceExecutor(newMySqlSaveOrderStrategy());executor1.save("001");OrderServiceExecutorexecutor2=newOrderServiceExecutor(newNoSqlSaveOrderStrategy());executor2.save("002");}}重构后,可以省去2个策略实现类,代码如下:publicstaticvoidmain(String[]args){OrderServiceExecutorexecutor1=newOrderServiceExecutor((StringorderNo)->System.out.println("order:"+orderNo+"savetomysql"));executor1.save("001");OrderServiceExecutorexecutor2=new
4OrderServiceExecutor((StringorderNo)->System.out.println("order:"+orderNo+"savetonosql"));executor2.save("002");}2.模板方法类图如下,核心思路是把一些通用的标准方法,在抽象父类里仅定义方法签名,实现逻辑交给子类。比如:会员系统中,每个商家都会有一些营销活动,需要推送某种信息给会员,但是不同的商家推送的内容可能不同,有些需要推送优惠券,有些需要积分通知。抽象模板类:publicabstractclassAbstractPushTemplate{publicvoidpush(intcustomerId,StringshopName){
5System.out.println("准备推送...");execute(customerId,shopName);System.out.println("推送完成
6");}abstractprotectedvoidexecute(intcustomerId,StringshopName);}优惠券的具体模板;publicclassPushCouponTemplateextendsAbstractPushTemplate{@Overrideprotectedvoidexecute(intcustomerId,StringshopName){System.out.println("会员:"+customerId+",你好,"+shopName+"送您一张优惠券");}}积分的具体模板;
7publicclassPushScoreTemplateextendsAbstractPushTemplate{@Overrideprotectedvoidexecute(intcustomerId,StringshopName){System.out.println("会员:"+customerId+",你好,"+shopName+"送您10个积分");}}使用示例:AbstractPushTemplatetemplate1=newPushCouponTemplate();template1.push(1,"糖果店");AbstractPushTemplatetemplate2=newPushScoreTemplate();template2.push(1,"服装店");显然如果模板的实现方式越多,子类就越多。使用java8重构后,可以把上面的3个模板(包括抽象类模板)减少到1个,参考下面:
8publicclassPushTemplateLambda{publicvoidpush(intcustomerId,StringshopName,Consumer
9");}}借助Consumer这个functioninterface,可以省去实现子类,具体的实现留到使用时再来决定,如:newPushTemplateLambda().push(1,"糖果店",(Object[]obj)->{System.out.println("会员:"+obj[0]+",你好,"+obj[1]+"送您一张优惠券");});newPushTemplateLambda().push(1,"服装店",(Object[]obj)->{
10System.out.println("会员:"+obj[0]+",你好,"+obj[1]+"送您10个积分");});3.观察者模式思路:基于某个Subject主题,然后一堆观察者Observer注册到主题上,有事件发生时,subject根据注册列表,去通知所有的observer。Observer接口:publicinterfaceObserver{voidnotify(StringorderNo);}Subject接口:publicinterfaceSubject{voidregisterObserver(Observero);
11voidnotifyAllObserver(StringorderNo);}Subject接口实现:publicclassSubjectImplimplementsSubject{privatefinalListlist=newArrayList<>();@OverridepublicvoidregisterObserver(Observero){list.add(o);}@OverridepublicvoidnotifyAllObserver(StringorderNo){list.forEach(c->c.notify(orderNo));}}观察者的二个实现:OrderObserver:publicclassOrderObserverimplementsObserver
12{@Overridepublicvoidnotify(StringorderNo){System.out.println("订单"+orderNo+"状态更新为【已支付】");}}StockObserver;publicclassStockObserverimplementsObserver{@Overridepublicvoidnotify(StringorderNo){System.out.println("订单"+orderNo+"已通知库房发货!");}}测试一把:staticvoidtest1(){Subjectsubject=newSubjectImpl();subject.registerObserver(newOrderObserver());
13subject.registerObserver(newStockObserver());subject.notifyAllObserver("001");}用java8重构后,接口可以提供默认实现方法,我们弄一个新的主题接口;publicinterfaceNewSubject{Listlist=newArrayList<>();defaultvoidregisterObserver(Observero){list.add(o);}defaultvoidnofityAllObserver(StringorderNo){list.forEach(c->c.notify(orderNo));}}使用:staticvoidtest2(){NewSubjectsubject=newNewSubject(){};
14subject.registerObserver((StringorderNo)->System.out.println("订单"+orderNo+"状态更新为【已支付】"));subject.registerObserver((StringorderNo)->System.out.println("订单"+orderNo+"已通知库房发货!"));subject.nofityAllObserver("002");}只用2个接口实现了观察者模式。4.责任链/职责链模式
15核心思想:每个处理环节,都有一个“指针”指向下一个处理者,类似链表一样。Processor接口:publicinterfaceProcessor{ProcessorgetNextProcessor();voidprocess(Stringparam);}抽象实现类:publicabstractclassAbstractProcessorimplementsProcessor{privateProcessornext;publicAbstractProcessor(Processorprocessor){this.next=processor;}@OverridepublicProcessorgetNextProcessor(){returnnext;
16}@Overridepublicabstractvoidprocess(Stringparam);}定义2个具体的实现:publicclassProcessorImpl1extendsAbstractProcessor{publicProcessorImpl1(Processorprocessor){super(processor);}@Overridepublicvoidprocess(Stringparam){System.out.println("processor1isprocessing:"+param);if(getNextProcessor()!=null){getNextProcessor().process(param);}}}
17及;publicclassProcessorImpl2extendsAbstractProcessor{publicProcessorImpl2(Processornext){super(next);}@Overridepublicvoidprocess(Stringparam){System.out.println("processor2isprocessing:"+param);if(getNextProcessor()!=null){getNextProcessor().process(param);}}}使用示例:staticvoidtest1(){Processorp1=newProcessorImpl1(null);Processorp2=newProcessorImpl2(p1);
18p2.process("somethinghappened");}用java8重构后,只需要一个新接口;@FunctionalInterfacepublicinterfaceNewProcessor{Consumerprocess(Stringparam);}同样的效果,可以写得很简洁:staticvoidtest2(){Consumerp1=param->System.out.println("processor1isprocessing:"+param);Consumerp2=param->System.out.println("processor2isprocessing:"+param);p2.andThen(p1).accept("somethinghappened");}andThen天然就是getNextProcessor的另一种表达。
19重要提示:什么时候该用lambda,什么时候不用,这是要看情况的,如果处理逻辑相对比较简单,可以用lamdba来重构,以便让代码更简洁易读,如果处理逻辑很复杂,应该还是用“类”。