设计模式之外观模式

本文探讨了外观模式在降低系统内部逻辑复杂性方面的作用,通过提供一个统一接口,使得调用者只需关注核心功能,而无需关心内部实现细节。作者通过示例展示了如何使用外观模式封装发送短信的业务,包括记录日志、数据库操作和邮件发送。然而,也指出过度耦合的问题,并提出通过额外的SenderService层进一步解耦,以提高代码的可维护性和遵循设计原则。
摘要由CSDN通过智能技术生成

外观模式就是提供一个统一的接口供外界调用,以降低内部逻辑复杂性。
在这里插入图片描述

如上图,还是拿目前最常用的模式来说,这个SmsServiceImpl里面在发送短信时,调用了一大堆其他内部逻辑。

要记录日志,要插入表数据,要调用外部接口发邮件等等。

如果要每次send(Sms)后都需要自己手动调用一次 LogService,DBService等里面的方法执行逻辑,我想谁都不愿意。

那么此处提供一个统一的接口,这个接口给controller调用,controller并不知道SmsService内部做了什么逻辑,他只需要知道调用这个SmsService.send()方法能够发送短信就行。

那么此处是不是算应用了外观模式呢?
在这里插入图片描述

定义一个SmsService,里面在send短信时,还调用了其他的内部逻辑。

/**
 * @author lw
 * @date 2022/3/29 0029
 * @description 短信服务
 */
public class SmsService {

    private DBService dbService = new DBService();
    private LogService logService = new LogService();
    private MailService mailService = new MailService();

    public void send(String toPhone, String content) {
        System.out.println("SmsService :" + content);

        //特殊号码发短信
        if("12306".equals(toPhone)){
            this.mailService.send(content);
        }
        dbService.writeDb();
        logService.log();
    }
}

调用者

SmsService smsService = new SmsService();
smsService.send("12306","hello world");

这确实看起来是外观模式,提供了一个统一的接口给外部,降低了内部逻辑复杂性。

调用者只需要调用一个send方法即可。

但是别忘了另一个原则,低耦合和单一原则

发送短信的方法里面还记录日志和数据库,还发送邮件,这像话么?

在移动CRM项目中,有一个一万多行的短信发送类,里面是各种 if-else 的判断业务,这些业务是用来判断是否发送短信的。

而真正发送短信的代码。提取出来只有几行,就是往短信表里面插入一行数据。

但如果让一个调用者如下面这么写代码,那岂不是在项目里面写的很烦,既要考虑发短信,还要判断是否记录日志和发邮件等等。万一以后变了呢?

所有设计都是为了以后易于扩展和变更,毕竟甲方的想法是很天马行空的。

		String toPhone = "12306";
        String content = "hello world";
        
        SmsService smsService = new SmsService();
        smsService.send(toPhone,content);

        DBService dbService = new DBService();
        LogService logService = new LogService();
        MailService mailService = new MailService();
        //特殊号码发短信
        if("12306".equals(toPhone)){
            mailService.send(content);
        }
        dbService.writeDb();
        logService.log();

当解决不了时,没有什么是包一层解决不了的。

/**
 * @author lw
 * @date 2022/3/30 0030
 * @description  消息发送
 */
public class SenderService {

    private DBService dbService = new DBService();
    private LogService logService = new LogService();
    private MailService mailService = new MailService();
    private SmsService smsService = new SmsService();

    public void send(String toPhone,String content){
        this.smsService.send(toPhone,content);
        
        //特殊号码发短信
        if("12306".equals(toPhone)){
            this.mailService.send(content);
        }
        dbService.writeDb();
        logService.log();

    }
}


/**
 * @author lw
 * @date 2022/3/29 0029
 * @description 短信服务
 */
public class SmsService {
    public void send(String toPhone, String content) {
        System.out.println("SmsService :" + content);
    }
}


String toPhone = "12306";
String content = "hello world";

SenderService senderService = new SenderService();
senderService.send(toPhone,content);

这样调用者就可以使用SenderService来发送消息,同时调用者也可以直接使用SmsService.send方法来仅仅发送短信。

外观模式并不妨碍调用者对子系统或者方法的访问

总结

外观模式,从外面看起来光鲜,哪管你金玉其外败絮其中,只要我调用你的方法调的方便即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值