百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

深入浅出外观模式 深入浅出ddr

yuyutoo 2024-10-20 13:09 2 浏览 0 评论

前言

不知道大家有没有比较过自己泡茶和去茶馆喝茶的区别,如果是自己泡茶需要自行准备茶叶、茶具和开水,而去茶馆喝茶,最简单的方式就是跟茶馆服务员说想要一杯什么样的茶,是铁观音、碧螺春还是西湖龙井?正因为茶馆有服务员,顾客无须直接和茶叶、茶具、开水等交互,整个泡茶过程由服务员来完成,顾客只需与服务员交互即可,整个过程非常简单省事。

以上这种场景类似设计模式中的外观模式,也叫做门面模式。外观模式通过引入一个新的外观类来实现该功能,外观类充当了“服务员”的角色,它为多个业务类的调用提供了一个统一的入口,简化了类与类之间的交互。本文我们一起来聊聊外观模式。

外观模式介绍

外观模式是一种使用频率非常高的结构型设计模式,它通过引入一个外观角色来简化客户端与子系统之间的交互,为复杂的子系统调用提供一个统一的入口,降低子系统与客户端的耦合度,且客户端调用非常方便。

外观模式结构图:

(1) Facade(外观角色):在客户端可以调用它的方法,在外观角色中可以知道相关的(一个或者多个)子系统的功能和责任;在正常情况下,它将所有从客户端发来的请求委派到相应的子系统去,传递给相应的子系统对象处理。

(2) SubSystem(子系统角色):在软件系统中可以有一个或者多个子系统角色,每一个子系统可以不是一个单独的类,而是一个类的集合,它实现子系统的功能;每一个子系统都可以被客户端直接调用,或者被外观角色调用,它处理由外观类传过来的请求;子系统并不知道外观的存在,对于子系统而言,外观角色仅仅是另外一个客户端而已。

案例场景

场景一:自己泡茶,整个过程应该是“烧开水->拿茶具->泡茶叶”然后喝茶。

定义一个饮用水类:DrinkableWater

/**
 * 烧水
 */
public class DrinkableWater {

    public DrinkableWater(){
        System.out.println("水准备好了");
    }

    //烧水
    public void facadeWater(){
        System.out.println("水烧开了");
    }
}

定义一个茶叶类:Tea

/**
 * 茶叶
 */
public class Tea {

    public Tea(){
        System.out.println("茶叶准备好了");
    }

    //取茶
    public void facadeTea(){
        System.out.println("可以泡茶了");
    }
}

定义一个茶杯类:TeaCup

/**
 * 茶杯
 */
public class TeaCup {

    public TeaCup(){
        System.out.println("茶杯准备好了");
    }

    //泡茶
    public void facadeTeaCup(Tea tea){
        tea.facadeTea();
        System.out.println("茶叶泡进茶杯了");
        System.out.println("茶冲好了");
    }
}

准备就绪,开始泡茶

public static void main(String[] args) {
    System.out.println("准备泡茶...");
    DrinkableWater drinkableWater = new DrinkableWater();
    TeaCup teaCup = new TeaCup();
    Tea tea = new Tea();

    drinkableWater.facadeWater();
    teaCup.facadeTeaCup(tea);
    System.out.println("喝茶...");
}

运行结果

准备泡茶...
水准备好了
茶杯准备好了
茶叶准备好了
水烧开了
可以泡茶了
茶叶泡进茶杯了
茶冲好了
喝茶...

场景二:去茶馆喝茶,不用自己动手泡茶了,直接告诉茶馆的服务员就行了。

定义一个服务员类:

/**
 * 服务员
 */
public class Waiter {

    private DrinkableWater drinkableWater = new DrinkableWater();
    private TeaCup teaCup = new TeaCup();
    private Tea tea = new Tea();

    //获得一杯茶
    public void getTea(){
        drinkableWater.facadeWater();
        teaCup.facadeTeaCup(tea);
    }
}

客户类:Customer

public class Customer {

    public static void main(String[] args) {
        //叫店小二
        Waiter waiter = new Waiter();
        //从店小二那获得一杯茶
        waiter.getTea();
    }
}

运行结果

水准备好了
茶杯准备好了
茶叶准备好了
水烧开了
可以泡茶了
茶叶泡进茶杯了
茶冲好了

在上面的泡茶的例子中,客人就是客户角色,茶馆服务员就是门面角色,茶具、饮用水、茶叶就是子系统角色。

代码看上去都很简单,也许你感觉二者区别不是很大,假如在软件开发中三个子系统之间有先后顺序,还有来自不同网络开销,我们通过门面模式提供的方法,就屏蔽了这些差异,让我们只需要调用门面角色提供给我们的方法即可。

外观模式优缺点

优点

(1)减少系统的相互依赖

如果我们不使用门面模式, 外界访问直接深入到子系统内部, 相互之间是一种强耦合关系, 你死我就死, 你活我才能活, 这样的强依赖是系统设计所不能接受的, 门面模式的出现就很好地解决了该问题, 所有的依赖都是对门面对象的依赖, 与子系统无关。

(2)提高安全性

想让你访问子系统的哪些业务就开通哪些逻辑, 不在门面上开通的方法, 你休想访问到。

缺点

(1)不能很好地限制客户端直接使用子系统类,如果对客户端访问子系统类做太多的限制则减少了可变性和灵活性。

(2)如果设计不当,增加新的子系统可能需要修改外观类的源代码,违背了开闭原则。

外观模式应用场景

(1)解决易用性问题

门面模式可以用来封装系统的底层实现,隐藏系统的复杂性,提供一组更加简单易用、更高层的接口。

(2)解决性能问题

通过将多个接口调用替换为一个门面接口调用,减少网络通信成本,提高客户端的响应速度。

(3)解决分布式事务问题

需要调用多个子系统的接口方法,而这些接口要么都成功,要么都失败,我们就可以利用门面模式包裹这些子系统接口,然后通过某种方法保证这些接口在一个事务中完成。

总结

在几乎所有的软件中都能够找到外观模式的应用,如绝大多数B/S系统都有一个首页或者导航页面,大部分C/S系统都提供了菜单或者工具栏,在这里,首页和导航页面就是B/S系统的外观角色,而菜单和工具栏就是C/S系统的外观角色,通过它们用户可以快速访问子系统,降低了系统的复杂程度。所有涉及到与多个业务对象交互的场景都可以考虑使用外观模式进行重构。

很多时候不是设计模式没有用,而是自己编程开发经验不足导致即使学了设计模式也很难驾驭。毕竟这些知识都是经过一些实际操作提炼出来的精华。

链接:https://juejin.cn/post/7223417872596516924

相关推荐

史上最全的浏览器兼容性问题和解决方案

微信ID:WEB_wysj(点击关注)◎◎◎◎◎◎◎◎◎一┳═┻︻▄(页底留言开放,欢迎来吐槽)●●●...

平面设计基础知识_平面设计基础知识实验收获与总结
平面设计基础知识_平面设计基础知识实验收获与总结

CSS构造颜色,背景与图像1.使用span更好的控制文本中局部区域的文本:文本;2.使用display属性提供区块转变:display:inline(是内联的...

2025-02-21 16:01 yuyutoo

写作排版简单三步就行-工具篇_作文排版模板

和我们工作中日常word排版内部交流不同,这篇教程介绍的写作排版主要是用于“微信公众号、头条号”网络展示。写作展现的是我的思考,排版是让写作在网格上更好地展现。在写作上花费时间是有累积复利优势的,在排...

写一个2048的游戏_2048小游戏功能实现

1.创建HTML文件1.打开一个文本编辑器,例如Notepad++、SublimeText、VisualStudioCode等。2.将以下HTML代码复制并粘贴到文本编辑器中:html...

今天你穿“短袖”了吗?青岛最高23℃!接下来几天气温更刺激……

  最近的天气暖和得让很多小伙伴们喊“热”!!!  昨天的气温到底升得有多高呢?你家有没有榜上有名?...

CSS不规则卡片,纯CSS制作优惠券样式,CSS实现锯齿样式

之前也有写过CSS优惠券样式《CSS3径向渐变实现优惠券波浪造型》,这次再来温习一遍,并且将更为详细的讲解,从布局到具体样式说明,最后定义CSS变量,自定义主题颜色。布局...

柠檬科技肖勃飞:大数据风控助力信用社会建设

...

你的自我界限够强大吗?_你的自我界限够强大吗英文

我的结果:A、该设立新的界限...

行内元素与块级元素,以及区别_行内元素和块级元素有什么区别?

行内元素与块级元素首先,CSS规范规定,每个元素都有display属性,确定该元素的类型,每个元素都有默认的display值,分别为块级(block)、行内(inline)。块级元素:(以下列举比较常...

让“成都速度”跑得潇潇洒洒,地上地下共享轨交繁华
让“成都速度”跑得潇潇洒洒,地上地下共享轨交繁华

去年的两会期间,习近平总书记在参加人大会议四川代表团审议时,对治蜀兴川提出了明确要求,指明了前行方向,并带来了“祝四川人民的生活越来越安逸”的美好祝福。又是一年...

2025-02-21 16:00 yuyutoo

今年国家综合性消防救援队伍计划招录消防员15000名

记者24日从应急管理部获悉,国家综合性消防救援队伍2023年消防员招录工作已正式启动。今年共计划招录消防员15000名,其中高校应届毕业生5000名、退役士兵5000名、社会青年5000名。本次招录的...

一起盘点最新 Chrome v133 的5大主流特性 ?

1.CSS的高级attr()方法CSSattr()函数是CSSLevel5中用于检索DOM元素的属性值并将其用于CSS属性值,类似于var()函数替换自定义属性值的方式。...

竞走团体世锦赛5月太仓举行 世界冠军杨家玉担任形象大使

style="text-align:center;"data-mce-style="text-align:...

学物理能做什么?_学物理能做什么 卢昌海

作者:曹则贤中国科学院物理研究所原标题:《物理学:ASourceofPowerforMan》在2006年中央电视台《对话》栏目的某期节目中,主持人问过我一个的问题:“学物理的人,如果日后不...

你不知道的关于这只眯眼兔的6个小秘密
你不知道的关于这只眯眼兔的6个小秘密

在你们忙着给熊本君做表情包的时候,要知道,最先在网络上引起轰动的可是这只脸上只有两条缝的兔子——兔斯基。今年,它更是迎来了自己的10岁生日。①关于德艺双馨“老艺...

2025-02-21 16:00 yuyutoo

取消回复欢迎 发表评论: