23种设计模式(1)-Facade设计模式

2023-05-16

前记

        曾经我遇见的一个需求是这样的,接口A有个方法void methodA(),类B需要实现接口A的methodA()方法,并且在类B中需要把methodA()方法内部处理逻辑获得的结果利用C类实例的某个方法进行持久化操作。由于技术功力尚浅,开始我左思右想就是不能实现这个需求。开始纠结于两个难题:1,methodA()方法返回值为void,我无法获得methodA()内部逻辑获得的数据,无法获得这些数据,也就无法利用持久化类C进行处理;2,methodA()方法入参又为空,我的持久化类C也无法注入。当时我就懵逼了。还好,突然脑海想起了曾学spring时遇见的模板类设计模式,于是浅显学了下的模板类设计模式轻松把这个难题搞定。解决方法为,B定义为抽象类,内部再另外定义一个抽象方法absMethod(C c),其入参为持久类C类型,在B类的methodA()方法中调用这个抽象方法absMethod(C c),这样持久化类则注入到了methodA()方法中,则可以对其中的数据进行持久化操作了。然后只需要用D类继承这个B类,并且实现这个B的absMethod(C c)方法,这样就可以把C实例间接传入methodA()方法。
        本博文并不是讲解模板类设计模式,只是借助遇见的这个问题的解决过程来强调设计模式对实现需求或学习技术源码是多么重要。不再废话,开始正文。


设计模式原则

这里写图片描述
以下为6种设计原则,直接摘录于别的博文或百度,这些内容的最终来源基本都是设计模式经典书籍《设计模式—可复用面向对象软件的基础》
1、开闭原则(Open Close Principle)
        开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。
2、里氏代换原则(Liskov Substitution Principle)
        里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
3、依赖倒转原则(Dependence Inversion Principle)
        这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。
4、接口隔离原则(Interface Segregation Principle)
        这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。
5、迪米特法则(最少知道原则)(Demeter Principle)
        为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。
6、合成复用原则(Composite Reuse Principle)
        原则是尽量使用合成/聚合的方式,而不是使用继承。


问题描述

        交流对于程序员这个职位来说是严重缺乏的,我们需要多锻炼啊。就举这个例子,当别人对我们说一句话,我们要领会别人的意思,粗略的讲这个过程主要是耳朵和大脑配合的结果。耳朵首先要“听”别人说的话,也就是获取别人对我们说的话。然后交给大脑去分析,我们才得以明白,用代码来模拟就如下。


不采用设计模式

Ear类

package com.facade.tradition;
/**
 * 
 * @author DC
 *
 */
public class Ear {

    /**
     * 别人说的话
     */
    private String words;

    /**
     * 听-获取别人说的话
     */
    public String getWords(String words){
        System.out.println("别人对我说的话:"+words);
        return words;
    }

    /**
     * 耳朵把话传给大脑
     */
    public boolean sendWordsToBrain(Brain brain,String words){
        return brain.sendWordsInBrain(words);
    }
}

Brain类

package com.facade.tradition;
/**
 * 
 * @author DC
 *
 */
public class Brain {

    /**
     * 话语
     */
    private String words;

    /**
     * 把话语记录大脑,别人说了话就设置true,反之false
     */
    public boolean sendWordsInBrain(String words){
        this.words=words;
        if(words==null){
            return false;
        }else{
            return true;
        }
    }

    /**
     * 分析话语
     */
    public void explainWords(){
        //模拟分析过程
        try {
            System.out.println("正在分析对方说的话是什么意思......");
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("额,原来你是这个意思!!");
    }
}

测试类TestTradition
我们来测试一下,当别人对我们说了一句话, 如果若想理解别人,在不采用门面模式是怎样的。如图:

package com.facade.tradition;
/**
 * 不利用设计模式,用代码来模拟这个我们和别人交流接听和理解别人话的过程
 * @author DC
 *
 */
public class TestTradition {

    public static void main(String[] args) {
        //这是我的耳朵和大脑
        Ear ear=new Ear();
        Brain brain=new Brain();

        //别人对我说了句话,我耳朵“听”到了
        String words=ear.getWords("你在干吗?");

        //但是我的耳朵并不理解别人说的什么意思,于是交给我的大脑
        ear.sendWordsToBrain(brain, words);

        //我的大脑分析话语
        brain.explainWords();
    }
}

在我耳朵和大脑的配合下,我终于明白了别人的话语,不容易啊,运行结果如下:
这里写图片描述

分析一下:
        再来看一下这个TestTradition代码,你是不是已经发现什么逻辑代码都得我们自己去完成,耳朵的逻辑处理我们得做,大脑的逻辑处理我们也得做。这导致了几个明显的问题:
         1. 测试类与Ear类代表的子系统和Brain类代表的子系统严重的耦合在了一起。
         2. 我们的测试类不仅与各个类所代表的子系统进行了交互,而且还必须了解两个子系统的类的内部实现情况。
         3. 我们系统中类的所有方法都暴露给了测试类,不论是需要暴露和不需要暴露的。
        再来看看上面提到的软件开发的设计原则,是不是这几个问题严重违背了一些设计原则。另外,我们并不需要了解和操作Ear或者Brain内部的一些方法。为解决这些问题,可以采用门面设计模式,也就是本博文的Facade设计模式。


采用Facade设计模式

Ear和Brain类同上
Head类:在此我们添加一个门面类,也就是本设计模式的核心类。其实,作为门面,你不觉得没有比Head更合适的类了吗,Head封装了Ear和Brain。那就定义Head为门面类,代码如下:

package com.facade.pattern;

import javax.swing.plaf.synth.SynthSpinnerUI;

/**
 * 模拟门面类,门面类一般是单例的,本例设计一个简单的单例
 * 
 * @author DC
 *
 */
public class Head {
    /**
     * 耳朵引用变量
     */
    public Ear ear=null;

    /**
     * 大脑引用变量
     */
    public Brain brain=null;

    /**
     * 头引用变量
     */
    public static Head head=null;

    private Head(){
        ear=new Ear();
        brain=new Brain();
    }

    /**
     * 获得Head头单例
     * @return
     */
    public static Head getInstance(){
        synchronized(Head.class){
            if(head==null){
                return new Head();              
            }
            return head;
        }
    }


    /**
     * "听"后明白了话语
     */
    public void explainWords(String words){

        //别人对我说了句话,我耳朵“听”到了
        String yourWords=ear.getWords(words);

        //但是我的耳朵并不理解别人说的什么意思,于是交给我的大脑
        ear.sendWordsToBrain(brain, yourWords);

        //我的大脑分析话语
        brain.explainWords();
    }

}

测试类TestFacade

package com.facade.pattern;
/**
 * 利用设计模式,用代码来模拟这个我们和别人交流接听和理解别人话的过程
 * @author DC
 *
 */
public class TestFacade {

    public static void main(String[] args) {
        //头引用,已经把具体的各个子系统连同其实现细节都封装在内部
        Head head=Head.getInstance();
        //别人说了,我就明白了,并不需要直接和Ear和Brain交互
        head.explainWords("你在干吗??");
    }
}

运行情况和不采用设计模式一样。

分析一下:
        再来看看这次发生了什么,Head门面类把Ear和Brain封装到了内部,并且把很多逻辑处理也封装到了内部,比如Ear实例获得话语,Ear实例传递话语,Brain实例记录话语这些都逻辑处理方法。通过这个门面类,只把和用户直接交互的方法explainWords()暴露给用户,其他的几个逻辑方法是属于系统内部方法,因此不需要交互也就不需要暴露出用户。这样的话,就解决了不采用Facade设计模式的几个问题。是不是感觉这个门面设计模式很简单了?


Facade设计模式

这里写图片描述
这里写图片描述
        facade门面角色:客户端和facade进行交互。此角色知道相关的(一个或者多个)子系统的功能和责任。当客户端想与众多的子系统进行交互时,facade角色会将所有从客户端发来的请求委派到相应的子系统去。
        subsystem子系统角色:可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。每一个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。

        Facade(外观)模式为子系统中的各类(或结构与方法)提供一个简明一致的界面,隐藏子系统的复杂性,使子系统更加容易使用。 Facade所面对的往往是多个类或其它程序单元,通过重新组合各类及程序单元,对外提供统一的接口/界面。门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面(Facade)对象进行。

Facade模式的几个使用场景:
  1、当你要为一个复杂子系统提供一个简单接口时。子系统往往因为不断演化而变得越来越复杂。大多数模式使用时都会产生更多更小的类。这使得子系统更具可重用性,也更容易对子系统进行定制,但这也给那些不需要定制子系统的用户带来一些使用上的困难。Facade可以提供一个简单的缺省视图,这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过Facade层。
  2、客户程序与抽象类的实现部分之间存在着很大的依赖性。引入Facade将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
  3、当你需要构建一个层次结构的子系统时,使用Facade模式定义子系统中每层的入口点,如果子系统之间是相互依赖的,你可以让它们仅通过Facade进行通讯,从而简化了它们之间的依赖关系。

特别注意

1, 【GOF】的书中指出:在门面模式中,通常只需要一个门面类,并且此门面类只有一个实例,换言之它是一个单例类。当然这并不意味着在整个系统里只能有一个门面类,而仅仅是说对每一个子系统只有一个门面类。或者说,如果一个系统有好几个子系统的话,每一个子系统有一个门面类,整个系统可以有数个门面类。
2,初学者往往以为通过继承一个门面类便可在子系统中加入新的行为,这是错误的。门面模式的用意是为子系统提供一个集中化和简化的沟通管道,而不能向子系统加入新的行为。

        以上比较专业的描述参考于书籍与别的博文。通俗一点理解,不采用facade设计模式就像现在的婚礼,采用facade设计模式和古代婚礼的整个过程是一样。
        不采用facade设计模式==现代婚礼。
        现在你遇见了一个心仪的女孩,恋爱了,打算和她结婚,上门提亲送彩礼什么的一切过程都得你亲力亲为。这个过程细节繁多。毕竟别人家的女儿,丈夫娘怎么会那么轻易让你得逞啦,已哭晕。
        采用facade设计模式==古代婚礼。
        周礼中规定的婚礼主要分六步,首先男方请媒人带上礼物去女方家里提亲,然后等女方家里回答,如果答应了,再让媒人带上男女双方的生辰去卜吉凶,如果可以结婚再选择一个日子,到了时间让男方和媒人带上礼物去迎娶。这下方便了,什么事都交给媒婆办了,连对方是不是女的我们自己都不能确定了。我们有什么事就找媒婆,媒婆从女方那里得到什么消息再反馈给我们。
        自己领悟吧,由于技术和理解有限就写这些了吧。望指教,谢谢!!


参考书籍或博文:
1,《设计模式—可复用面向对象软件的基础》(很不错的书籍)
2,《JAVA设计模式之门面模式(外观模式)》
3,《JAVA设计模式十九–Facade(外观模式)》
4,《Java开发中的23种设计模式详解(转)》
5,《设计模式(15)-Facade Pattern》

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

23种设计模式(1)-Facade设计模式 的相关文章

  • vim 中批量添加注释(块选择模式)

    批量注释 xff1a Ctrl 43 v 进入块选择模式 xff0c 然后移动光标选中你要注释的行 xff0c 再按大写的 I 进入行首插入模式输入注释符号如 或 xff0c 输入完毕之后 xff0c 按两下 ESC xff0c Vim 会
  • 在github找到指定版本代码并下载

    以MPC HC代码为例子 记下过程 备忘 具体版本为nightly 1 7 0 154 1 通过官网http mpc hc org downloads 找到github地址https github com mpc hc mpc hc 2 通
  • 光盘自动运行程序的秘密

    光盘自动运行程序的秘密 光盘一放入光驱就会自动被执行 xff0c 主要依靠两个文件 xff0c 一是光盘上的 Cdvsd vxd 会随时侦测光驱中是否有放入光盘的动作 xff0c 如果有的话 xff0c 便开始寻找光盘根目录下的AutoRu
  • mysql生成不重复随机数(unique number generation)

    问题来源 业务中有时会遇到要生成不重复随机数的情况 xff0c 例如 xff0c 新生成一个商品编号 房间编号 或者其他物品编号等 不愿意采用表的自增索引 id xff0c 同时又希望新生成的编号是不重复的 这就需要考验mysql的随机数功
  • 【2015/IE】Variational Autoencoder based Anomaly Detection using Reconstruction Probability

    原文首发于个人站点 xff1a 基于变分自编码器重构概率的异常检测模型 个人公众号 xff1a DreamHub 文章链接 xff1a Variational Autoencoder based Anomaly Detection usin
  • 计算机视觉:相机模型与参数标定

    一 相机投影模型 1 小孔成像 2 相机模型中的四个平面坐标系 3 像主点偏移 4 畸变现象与内参矩阵 5 外参矩阵 二 相机标定 xff1a 张正友棋盘格标定法 1 张正友棋盘格标定法描述 2 计算外参和内参 2 1 计算单应性矩阵H 2
  • 电子信息专业英语

    61 61 61 61 61 61 61 61 61 61 普通电子类 名词 1 diode 英 39 da d n 电子 二极管 2 oscillator 英 39 s le t r n 电子 振荡器 xff1b 摆动物 xff1b 动摇
  • 计算机视觉中的MAP的理解(mean average precision)

    计算机视觉中的MAP的理解 xff08 mean average precision xff09 精准率 Precision xff0c P值 和召回率 Recall xff0c R值 下面我们来讲AP xff08 average prec
  • 机器学习方法原理及编程实现--07.隐马尔科夫及其在卡尔曼滤波中的应用

    文章列表 1 机器学习方法原理及编程实现 01 K近邻法 实现MNIST数据分类 2 机器学习方法原理及编程实现 02 决策树 3 机器学习方法原理及编程实现 03 朴素贝叶斯分类器 实现MNIST数据分类 4 机器学习方法原理及编程实现
  • 安装realsense出现的一些问题

    借鉴代码 xff1a Ubuntu18 04安装librealsense2 SDK Linux 考高分网 报错 xff1a 之前安装的时候老是提示找不到realsense2 camera那几个包 xff0c 但是他就在 ros里面 xff0
  • Java程序员必读的10本书籍

    以下列出了10本书 xff0c 对于任何希望提高Java知识和理解的Java程序员来说都是必不可少的 如果你是一名程序员 xff0c 想知道如何提高你对Java的了解或者成为更好的Java开发人员 xff0c 那你就来对地方了 在本文中 x
  • ros基础必看之各个frame的理解

    文章目录 常见的坐标系坐标系的约定坐标系变换的计算Map之间的切换添加 如果觉得好请收藏点赞 frame id xff1a 用来告诉你 xff0c 发布的数据是来自哪一个坐标系的 ros中常见的坐标系 转载链接 现在小车进行移动 如图 1
  • 嵌入式 Rust 之书---第一章 引言

    目录 谁适合使用嵌入式Rust 范围 本书适用于谁 如何使用本书 为本书作贡献 1 1 了解你的硬件 1 2 一个no std的Rust环境 1 3 工具 1 4 安装工具 1 4 1 Linux 1 4 2 macOS 1 4 3 Win
  • 质心跟踪算法

    质心跟踪算法依赖于 xff08 1 xff09 现有对象质心 xff08 即 xff0c 质心跟踪器之前已经看到的对象 xff09 与 xff08 2 xff09 视频中后续帧之间的新对象质心之间的欧几里得距离 质心跟踪算法的主要假设是一个
  • 为什么我要刷leetcode!

    从今天开始我会每天坚持刷leetcode 为什么要这么做呢 xff1f 其实也是闲的哈哈哈哈 xff0c 被病毒困在家里那里也去不了 xff0c 那就不如来刷代码吧 xff01 其实不管是C 43 43 还是C还是java等各种各样的计算机
  • 标准模板库学习(5)----算法之非修正序列算法

    算法是STL的中枢 xff0c STL提供了算法库 xff0c 算法库都是模板函数 xff0c 主要分为四类 xff0c 非修正序列算法 修正序列算法 排序算法和数值算法 本文介绍非修正序列算法 adjacent find start en
  • Ubuntu中apt update和upgrade的区别

    原文链接 xff1a https blog csdn net CSDN duomaomao article details 77802673 简要说明 xff1a apt update xff1a 只检查 xff0c 不更新 xff08 已
  • Java中的信号量(Semaphore)

    初识Semaphore 信号量 xff0c 也可以称其为 信号灯 xff0c 它的存在就如同生活中的红绿灯一般 xff0c 用来控制车辆的通行 在程序员眼中 xff0c 线程就好比行驶的车辆 xff0c 程序员就可以通过信号量去指定线程是否
  • USB 2.0_ser!或者U232-P9 型USB转串Win7 32位或64位驱动 以及 USB转串串口序号查看和设置

    前几天叫同事在电脑城买了个USB转串数据线 xff0c 但是回来后在网上找了很多驱动都不行 觉得这个问题花了不少时间的 xff0c 我也拆开了 xff0c 打算按照芯片型号找驱动 xff0c 但是看不到芯片型号 现在终于找到合适的了 把这个
  • 《Java核心技术卷1》

    第3章 Java的基础程序设计结构 整型 用int类型表示一百万可以这么写 xff08 since 1 7 xff09 span class token keyword int span a span class token operato

随机推荐

  • voxl-flight quick start

    voxl flight 官方地址 xff1a https www modalai com 硬件及接口 两个版本 Snapdragon 821 xff1a 四核最高2 15GH xff0c GPU xff0c 2xDSP 视频支持 xff1a
  • 零基础如何学习优达学城的《无人驾驶入门》?

    因为感兴趣 xff0c 而且看好无人驾驶行业 xff0c 我学习了优达学城的 无人驾驶入门 课程 最近整理了无人驾驶领域的资料 xff0c 写成文章分享给大家 作为系列文章的第一篇 xff0c 我想介绍一下 无人驾驶入门 这门课 xff0c
  • realsense D435 标定(calibration)

    realsense D435 标定 文章目录 realsense D435 标定1 确定是否需要标定设备信息步骤操作打印标定目标开启标定程序 校正结果展示比较 文档 1 确定是否需要标定 工具 Depth Quality Tool 要求 将
  • 如何在linux执行PHP文件

    1 刚导入到linux系统中文件是没有可执行权 2 首先赋予文件可执行权限 chmod 43 x 文件名 例如 xff1a chomd 43 x czrkdjb php 如果要用 czrkdjb php执行 xff0c 需要在czrkdjb
  • 阿里P8大佬亲自讲解!写给程序员的Flutter详细教程,灵魂拷问

    我们程序员经常迷茫于有太多东西要学 xff0c 有些找不到方向 不知所措 很多程序员都愿意说 xff0c 我想变得更好 xff0c 但是更好是什么却很模糊 xff0c 同时我们又不知道该怎么样去做 我们的生命如此短暂 xff0c 作为程序员
  • VSCode 连接远程服务器使用图形化界面(GUI)

    1 基本环境 本地电脑系统 xff1a window10 远程服务器系统 xff1a Ubuntu18 04 2 VSCode版本 xff1a 1 51 1 2 问题描述 vscod提供了优秀的远程连接插件 xff08 Remote SSH
  • curl 命令大全及常用实例

    一 xff0c curl命令参数 a append 上传文件时 xff0c 附加到目标文件 A user agent lt string gt 设置用户代理发送给服务器 anyauth 可以使用 任何 身份验证方法 b cookie lt
  • 关于putty不能连接虚拟机的问题解决

    一 首先需要ping 一下 xff0c 看是否能ping通 xff0c 如果正常进入下一步 二 进入虚拟机终端输入 ssh localhost 如果提示 ssh connect to host localhost port 22 Conne
  • postman进行http接口测试

    HTTP的接口测试工具有很多 xff0c 可以进行http请求的方式也有很多 xff0c 但是可以直接拿来就用 xff0c 而且功能还支持的不错的 xff0c 我使用过的来讲 xff0c 还是postman比较上手 优点 xff1a 1 支
  • Linux系统迁移(将配置好的系统安装到其它电脑上)

    Linux系统迁移 说在前面 xff1a 下面有几个教程链接 xff0c 我都是通过这几个链接来完成的系统备份与系统恢复 并且遇到过一些问题 xff0c 踩过一些坑 建议先看完我的说明再进行操作 xff0c 少走弯路 没有图是因为下面分享的
  • 搭建 公网FTP服务器 外网访问

    我是在ubuntu 20 04 上配置的 xff0c 需要用到公网IP 没有公网IP的 xff0c 可以考虑花生壳这类应用来做内网穿透 1 配置FTP服务器 安装vsftpd sudo apt install vsftpd sudo vim
  • clang-format配置与使用

    clang format配置与使用 参考教程 1 安装 下载clang format xff0c 设置环境变量 我使用的是vscode扩展中的clang format 位于 xff1a extensions ms vscode cpptoo
  • AI一般是用来制作什么的

    AI一般用来制作logo 分页 xff0c 海报等等 面板堆栈的话就是很多功能堆放的位置 一般打印出来的话用cmyk模式 如果是在web端的话用RGB模式 xff0c 因为cmyk模式在你进行存储的过程中颜色可能会丢失 出血值就是在你打印东
  • Eclipse安装插件的三种方式

    本文介绍Eclipse插件的安装方法 Eclipse插件的安装方法大体有三种 xff1a 直接复制 使用link文件 xff0c 以及使用eclipse自带的图形界面的插件安装方法 AD xff1a 做为当下最流行的开源IDE之一 xff0
  • 获取realsense内参

    文章目录 xff11 xff0e 无畸变 xff12 xff0e Brown Conrady 畸变模型3 Opencv 里畸变图像矫正过程 xff11 xff0e 无畸变 相机内参包括相机矩阵参数和畸变系数 相机内参矩阵为3 3的矩阵 xf
  • 十年研发经验工程师的嵌入式学习书籍大推荐

    从事嵌入式研发行业十年 xff0c 认为学习就是要不断的吸纳知识 xff0c 在研发过程中 xff0c 经常会遇到一些问题 xff0c 这种发现问题并解决问题的过程就是进步 为什么选择学习嵌入式 xff1f 嵌入式系统无疑是当前最热门最有发
  • js手机号正则表达式验证

    看到网上很多代码 都很复杂 xff0c 还包括以中文开头的86 xff0c 17951 xff0c 其实谁会填这么多 xff0c 无非是检验一下他们是否位数对不对 xff0c 开头有没有写错而已 下面我们从百度百科的手机号码历程来看 xff
  • 正则验证匹配中文姓名全部源字符串

    这个是验证匹配中文姓名的全部源串 xff0c 在网上找了很久 xff0c 大都是验证匹配含有中文 xff0c 就在网上某人提供的正则的基础上修改成了验证所填姓名的每个字符 xff0c 只有都匹配才能验证通过 该正则为 xff1a u4e00
  • 域名,网站名和URL区别

    要写一个正则表达式来验证输入域名是否有正确 xff0c 一直以为例如http www baidu com类似于这种才是网站域名 xff0c 经过百度才发现自己的认知是错误的 以下转载于百度经验 xff1a http jingyan baid
  • 23种设计模式(1)-Facade设计模式

    前记 曾经我遇见的一个需求是这样的 xff0c 接口A有个方法void methodA xff0c 类B需要实现接口A的methodA 方法 xff0c 并且在类B中需要把methodA 方法内部处理逻辑获得的结果利用C类实例的某个方法进行