涨姿势,Java 重构设计模式,厉害!

沙海 2022年7月31日04:29:04Java评论5字数 8347阅读27分49秒阅读模式
摘要

智能摘要

智能摘要文章源自JAVA秀-https://www.javaxiu.com/71296.html

点击上方"Java基基",选择"设为星标"做积极的人,而不是积极废人!基于某个Subject主题,然后一堆观察者Observer注册到主题上,有事件发生时,subject根据注册列表,去通知所有的observer。每个处理环节,都有一个"指针"指向下一个处理者,类似链表一样。什么时候该用lambda,什么时候不用,这是要看情况的,如果处理逻辑相对比较简单,可以用lamdba来重构,以便让代码更简洁易读,如果处理逻辑很复杂,应该还是用"类"。文章源自JAVA秀-https://www.javaxiu.com/71296.html

原文约 4260 | 图片 10 | 建议阅读 9 分钟 | 评价反馈文章源自JAVA秀-https://www.javaxiu.com/71296.html

涨姿势,Java 重构设计模式,厉害!

点击关注 ? Java基基 文章源自JAVA秀-https://www.javaxiu.com/71296.html

点击上方“Java基基”,选择“设为星标”文章源自JAVA秀-https://www.javaxiu.com/71296.html

做积极的人,而不是积极废人!文章源自JAVA秀-https://www.javaxiu.com/71296.html

每天 14:00 更新文章,每天掉亿点点头发...文章源自JAVA秀-https://www.javaxiu.com/71296.html

文章源自JAVA秀-https://www.javaxiu.com/71296.html

源码精品专栏文章源自JAVA秀-https://www.javaxiu.com/71296.html

 文章源自JAVA秀-https://www.javaxiu.com/71296.html

文章源自JAVA秀-https://www.javaxiu.com/71296.html

来源:cnblogs.com/yjmyzz/p/refactor文章源自JAVA秀-https://www.javaxiu.com/71296.html

-design-pattern-using-java8.html文章源自JAVA秀-https://www.javaxiu.com/71296.html

涨姿势,Java 重构设计模式,厉害!文章源自JAVA秀-https://www.javaxiu.com/71296.html

java8中提供的很多新特性可以用来重构传统设计模式中的写法,下面是一些示例:文章源自JAVA秀-https://www.javaxiu.com/71296.html

一、策略模式

涨姿势,Java 重构设计模式,厉害!文章源自JAVA秀-https://www.javaxiu.com/71296.html

上图是策略模式的类图,假设我们现在要保存订单,OrderService接口定义要做什么,而NoSqlSaveOrderStragegy以及MySqlSaveOrderStrategy则提供了二种策略,分别是保存到nosql数据库,以及传统的mysql关系型数据库,最后在OrderServiceExecutor中通过构造函数注入最终要使用的策略。文章源自JAVA秀-https://www.javaxiu.com/71296.html

传统写法,这个场景至少得4个类,代码如下:文章源自JAVA秀-https://www.javaxiu.com/71296.html

OrderService接口:文章源自JAVA秀-https://www.javaxiu.com/71296.html

public interface OrderService {    void saveOrder(String orderNo);}

Mysql策略实现:文章源自JAVA秀-https://www.javaxiu.com/71296.html

public class MySqlSaveOrderStrategy implements OrderService {    @Override    public void saveOrder(String orderNo) {        System.out.println("order:" + orderNo + " save to mysql");    }}

Nosql策略实现文章源自JAVA秀-https://www.javaxiu.com/71296.html

public class NoSqlSaveOrderStrategy implements OrderService {    @Override    public void saveOrder(String orderNo) {        System.out.println("order:" + orderNo + " save to nosql");    }} 

使用策略的辅助"容器"文章源自JAVA秀-https://www.javaxiu.com/71296.html

public class OrderServiceExecutor {     private final OrderService service;     public OrderServiceExecutor(OrderService service) {        this.service = service;    }     public void save(String orderNo) {        this.service.saveOrder(orderNo);    } }  

运行测试类:文章源自JAVA秀-https://www.javaxiu.com/71296.html

public class OrderServiceTest {    public static void main(String[] args) {        OrderServiceExecutor executor1 = new OrderServiceExecutor(new MySqlSaveOrderStrategy());        executor1.save("001");        OrderServiceExecutor executor2 = new OrderServiceExecutor(new NoSqlSaveOrderStrategy());        executor2.save("002");    }}  

重构后,可以省去2个策略实现类,代码如下:文章源自JAVA秀-https://www.javaxiu.com/71296.html

public static void main(String[] args) {    OrderServiceExecutor executor1 = new OrderServiceExecutor((String orderNo) -> System.out.println("order:" + orderNo + " save to mysql"));    executor1.save("001");     OrderServiceExecutor executor2 = new OrderServiceExecutor((String orderNo) -> System.out.println("order:" + orderNo + " save to nosql"));    executor2.save("002");}

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能文章源自JAVA秀-https://www.javaxiu.com/71296.html

  • 项目地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro文章源自JAVA秀-https://www.javaxiu.com/71296.html

  • 视频教程:https://doc.iocoder.cn/video/文章源自JAVA秀-https://www.javaxiu.com/71296.html

二、模板方法

类图如下,核心思路是把一些通用的标准方法,在抽象父类里仅定义方法签名,实现逻辑交给子类。文章源自JAVA秀-https://www.javaxiu.com/71296.html

比如:会员系统中,每个商家都会有一些营销活动,需要推送某种信息给会员,但是不同的商家推送的内容可能不同,有些需要推送优惠券,有些需要积分通知。文章源自JAVA秀-https://www.javaxiu.com/71296.html

涨姿势,Java 重构设计模式,厉害!文章源自JAVA秀-https://www.javaxiu.com/71296.html

抽象模板类:文章源自JAVA秀-https://www.javaxiu.com/71296.html

public abstract class AbstractPushTemplate {     public void push(int customerId, String shopName) {        System.out.println("准备推送...");        execute(customerId, shopName);        System.out.println("推送完成\n");    }     abstract protected void execute(int customerId, String shopName);}

优惠券的具体模板文章源自JAVA秀-https://www.javaxiu.com/71296.html

public class PushCouponTemplate extends AbstractPushTemplate {     @Override    protected void execute(int customerId, String shopName) {        System.out.println("会员:" + customerId + ",你好," + shopName + "送您一张优惠券");    }}

积分的具体模板文章源自JAVA秀-https://www.javaxiu.com/71296.html

public class PushScoreTemplate extends AbstractPushTemplate {     @Override    protected void execute(int customerId, String shopName) {        System.out.println("会员:" + customerId + ",你好," + shopName + "送您10个积分");    }}

使用示例:文章源自JAVA秀-https://www.javaxiu.com/71296.html

AbstractPushTemplate template1 = new PushCouponTemplate();template1.push(1, "糖果店"); AbstractPushTemplate template2 = new PushScoreTemplate();template2.push(1, "服装店");  

显然如果模板的实现方式越多,子类就越多。使用java8重构后,可以把上面的3个模板(包括抽象类模板)减少到1个,参考下面:文章源自JAVA秀-https://www.javaxiu.com/71296.html

public class PushTemplateLambda {     public void push(int customerId, String shopName, Consumer<Object[]> execute) {        System.out.println("准备推送...");        Object[] param = new Object[]{customerId, shopName};        execute.accept(param);        System.out.println("推送完成\n");    }}

借助Consumer<T>这个function interface,可以省去实现子类,具体的实现留到使用时再来决定,如:文章源自JAVA秀-https://www.javaxiu.com/71296.html

new PushTemplateLambda().push(1, "糖果店", (Object[] obj) -> {    System.out.println("会员:" + obj[0] + ",你好," + obj[1] + "送您一张优惠券");}); new PushTemplateLambda().push(1, "服装店", (Object[] obj) -> {    System.out.println("会员:" + obj[0] + ",你好," + obj[1] + "送您10个积分");});

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能文章源自JAVA秀-https://www.javaxiu.com/71296.html

  • 项目地址:https://gitee.com/zhijiantianya/yudao-cloud文章源自JAVA秀-https://www.javaxiu.com/71296.html

  • 视频教程:https://doc.iocoder.cn/video/文章源自JAVA秀-https://www.javaxiu.com/71296.html

三、观察者模式

涨姿势,Java 重构设计模式,厉害!文章源自JAVA秀-https://www.javaxiu.com/71296.html

思路:基于某个Subject主题,然后一堆观察者Observer注册到主题上,有事件发生时,subject根据注册列表,去通知所有的observer。文章源自JAVA秀-https://www.javaxiu.com/71296.html

Observer接口:文章源自JAVA秀-https://www.javaxiu.com/71296.html

public interface Observer {    void notify(String orderNo);}

Subject接口:文章源自JAVA秀-https://www.javaxiu.com/71296.html

public interface Subject {    void registerObserver(Observer o);    void notifyAllObserver(String orderNo);}

Subject接口实现:文章源自JAVA秀-https://www.javaxiu.com/71296.html

public class SubjectImpl implements Subject {    private final List<Observer> list = new ArrayList<>();    @Override    public void registerObserver(Observer o) {        list.add(o);    }    @Override    public void notifyAllObserver(String orderNo) {        list.forEach(c -> c.notify(orderNo));    }}  

观察者的二个实现:文章源自JAVA秀-https://www.javaxiu.com/71296.html

OrderObserver:文章源自JAVA秀-https://www.javaxiu.com/71296.html

public class OrderObserver implements Observer {    @Override    public void notify(String orderNo) {        System.out.println("订单 " + orderNo + " 状态更新为【已支付】");    }}

StockObserver:文章源自JAVA秀-https://www.javaxiu.com/71296.html

public class StockObserver implements Observer {    @Override    public void notify(String orderNo) {        System.out.println("订单 " + orderNo + " 已通知库房发货!");    }}

测试一把:文章源自JAVA秀-https://www.javaxiu.com/71296.html

static void test1() {    Subject subject = new SubjectImpl();    subject.registerObserver(new OrderObserver());    subject.registerObserver(new StockObserver());    subject.notifyAllObserver("001");}  

用java8重构后,接口可以提供默认实现方法,我们弄一个新的主题接口文章源自JAVA秀-https://www.javaxiu.com/71296.html

public interface NewSubject {     List<Observer> list = new ArrayList<>();     default void registerObserver(Observer o) {        list.add(o);    }     default void nofityAllObserver(String orderNo) {        list.forEach(c -> c.notify(orderNo));    }}

使用:文章源自JAVA秀-https://www.javaxiu.com/71296.html

static void test2() {    NewSubject subject = new NewSubject() {    };    subject.registerObserver((String orderNo) -> System.out.println("订单 " + orderNo + " 状态更新为【已支付】"));    subject.registerObserver((String orderNo) -> System.out.println("订单 " + orderNo + " 已通知库房发货!"));    subject.nofityAllObserver("002");}

只用2个接口实现了观察者模式。文章源自JAVA秀-https://www.javaxiu.com/71296.html

四、责任链/职责链模式

涨姿势,Java 重构设计模式,厉害!文章源自JAVA秀-https://www.javaxiu.com/71296.html

核心思想:每个处理环节,都有一个“指针”指向下一个处理者,类似链表一样。文章源自JAVA秀-https://www.javaxiu.com/71296.html

Processor接口:文章源自JAVA秀-https://www.javaxiu.com/71296.html

public interface Processor {     Processor getNextProcessor();     void process(String param);}

抽象实现类文章源自JAVA秀-https://www.javaxiu.com/71296.html

public abstract class AbstractProcessor implements Processor {     private Processor next;     public AbstractProcessor(Processor processor) {        this.next = processor;    }     @Override    public Processor getNextProcessor() {        return next;    }     @Override    public abstract void process(String param);}

定义2个具体的实现文章源自JAVA秀-https://www.javaxiu.com/71296.html

public class ProcessorImpl1 extends AbstractProcessor {     public ProcessorImpl1(Processor processor) {        super(processor);    }     @Override    public void process(String param) {        System.out.println("processor 1 is processing:" + param);        if (getNextProcessor() != null) {            getNextProcessor().process(param);        }    }}

文章源自JAVA秀-https://www.javaxiu.com/71296.html

public class ProcessorImpl2 extends AbstractProcessor {     public ProcessorImpl2(Processor next) {        super(next);    }     @Override    public void process(String param) {        System.out.println("processor 2 is processing:" + param);        if (getNextProcessor() != null) {            getNextProcessor().process(param);        }    }}

使用示例:文章源自JAVA秀-https://www.javaxiu.com/71296.html

static void test1() {    Processor p1 = new ProcessorImpl1(null);    Processor p2 = new ProcessorImpl2(p1);    p2.process("something happened");}

用java8重构后,只需要一个新接口文章源自JAVA秀-https://www.javaxiu.com/71296.html

@FunctionalInterfacepublic interface NewProcessor {    Consumer<String> process(String param);}

同样的效果,可以写得很简洁:文章源自JAVA秀-https://www.javaxiu.com/71296.html

static void test2() {    Consumer<String> p1 = param -> System.out.println("processor 1 is processing:" + param);    Consumer<String> p2 = param -> System.out.println("processor 2 is processing:" + param);    p2.andThen(p1).accept("something happened");}

andThen天然就是getNextProcessor的另一种表达。文章源自JAVA秀-https://www.javaxiu.com/71296.html

重要提示:什么时候该用lambda,什么时候不用,这是要看情况的,如果处理逻辑相对比较简单,可以用lamdba来重构,以便让代码更简洁易读,如果处理逻辑很复杂,应该还是用“类”。文章源自JAVA秀-https://www.javaxiu.com/71296.html

欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢文章源自JAVA秀-https://www.javaxiu.com/71296.html

涨姿势,Java 重构设计模式,厉害!文章源自JAVA秀-https://www.javaxiu.com/71296.html

已在知识星球更新源码解析如下:文章源自JAVA秀-https://www.javaxiu.com/71296.html

涨姿势,Java 重构设计模式,厉害!文章源自JAVA秀-https://www.javaxiu.com/71296.html

涨姿势,Java 重构设计模式,厉害!文章源自JAVA秀-https://www.javaxiu.com/71296.html

涨姿势,Java 重构设计模式,厉害!文章源自JAVA秀-https://www.javaxiu.com/71296.html

涨姿势,Java 重构设计模式,厉害!文章源自JAVA秀-https://www.javaxiu.com/71296.html

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。文章源自JAVA秀-https://www.javaxiu.com/71296.html

提供近 3W 行代码的 SpringBoot 示例,以及超 6W 行代码的电商微服务项目。文章源自JAVA秀-https://www.javaxiu.com/71296.html

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。文章源自JAVA秀-https://www.javaxiu.com/71296.html

文章源自JAVA秀-https://www.javaxiu.com/71296.html

文章有帮助的话,在看,转发吧。谢谢支持哟 (*^__^*)
文章源自JAVA秀-https://www.javaxiu.com/71296.html
继续阅读
速蛙云 - 极致体验,强烈推荐!!!购买套餐就免费送各大视频网站会员!快速稳定、独家福利社、流媒体稳定解锁!速度快,全球上网、视频、游戏加速、独立IP均支持!基础套餐性价比很高!这里不多说,我一直正在使用,推荐购买:https://www.javaxiu.com/59919.html
weinxin
资源分享QQ群
本站是JAVA秀团队的技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
沙海
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定