设计模式之外观模式

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

如上图,还是拿目前最常用的模式来说,这个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方法来仅仅发送短信。

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

总结

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

posted @   伟衙内  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示