前言:为什么要一次讲解这两个模式,说点骚话:因为比较简单(*^_^*),其实是他们两个有相似和有时候我们容易搞混概念。

讲到这两个设计模式与另外一个“装饰者模式”也有相似,他们三个按照结构模式分类都属于“结构性模式”,所有我们接下来就来看什么是适配器模式和外观模式。

另外装饰模式可以看我的另一篇博文→Head First设计模式——装饰者模式

一、适配器模式

适配器对应到我们现实生活中的例子,最典型的就是插头接口适配器,比如我们买的有些港版手机充电头是圆形三角插头,而大陆的三角电源插板插不进去港版的插头。

这时候我们就会在某宝上买个转接头转换一下,而这个转接头就是适配器,用它来适配港版手机充电头让他能够插入到我们的电源插板里面。

在设计模式中这个适配器是什么,用程序如何表现,先让我举个栗子:我们有一只鸭子,一只鸡,我们如何通过适配器转换鸭和鸡。

鸭子有很多种,我们定义一个鸭子的接口,然后以绿头鸭为例。关于这个绿头鸭在策略模式也有用到,可以看看我另一篇绿头鸭如何搅动策略模式→Head First设计模式——策略模式

    public  interface Duck
{
//叫
public void Quack();
//飞
public void Fly();
} public class GreenDuck : Duck
{
public void Fly()
{
Console.WriteLine("绿头鸭,飞");
} public void Quack()
{
Console.WriteLine("绿头鸭,呱呱叫");
}
}

  同样我们定义一个鸡的接口,和一只母鸡的类

    public  interface Chicken
{
//叫
public void Gobble();
//飞
public void Fly();
} public class Hen : Chicken
{ public void Gobble()
{
Console.WriteLine("母鸡,咯咯叫");
} public void Fly()
{
Console.WriteLine("母鸡,飞");
} }

  鸭子和母鸡的叫声不一样,现在我们让母鸡来冒充鸭子,利用适配器模式如何做。 直接看代码吧

    /// <summary>
/// 母鸡适配器
/// 适配母鸡让它变成鸭子
/// </summary>
public class HenAdapter : Duck
{
Chicken chicken;
public HenAdapter(Chicken chicken)
{
this.chicken = chicken;
}
public void Quack()
{
//调用母鸡咯咯叫
chicken.Gobble();
} public void Fly()
{
//调用母鸡飞
chicken.Fly();
} }

  测试母鸡适配器

如上我们使用母鸡适配器将母鸡适配成了鸭子,鸭子也可以用适配器将鸭子适配成母鸡,适配器模式定义:

适配器模式:将一个类的接口,装换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。

与适配器看起来相似的装饰者模式是包装对象的行为或责任,装饰者被包装后可能会继续被包装,他们不装换接口,而适配器则一定会进行接口的转换。

适配的工作是将一个接口转换成另外一个接口,虽然大多数适配器采取的例子都是让一个适配器包装一个被适配者,但是有时候我们需要让一个适配器包装多个被适配者。

而这实际又涉及到另外一个模式,就是外观模式,我们常常将适配器模式和外观模式混为一谈,那接着就来讲解外观模式。

二、外观模式

外观模式以家庭影院为例,家庭影院有许多组件构成,比如:显示屏、DVD、音响、灯光等等。

当我们要看电影的时候要打开显示屏,打开DVD,打开音响,关闭灯光等一系列动作,将这些动作写成类方法的调用

            Screen screen = new Screen();
DVD dvd = new DVD();
SoundEngineer sound = new SoundEngineer();
Light light = new Light(); screen.Down();
dvd.PlayDVD();
sound.TurnOn();
light.TurnOff();

可以看到每次我们要使用就要调用一篇这些方法,如果要关闭呢,我们也需要调用一篇。而我们正需要的就是一个外观:通过实现一个提供更合理的接口的外观类。

还是看代码吧

 public class HomeThreaterFacade
{
Screen screen;
DVD dvd;
SoundEngineer sound;
Light light; public HomeThreaterFacade(Screen screen, DVD dvd, SoundEngineer sound, Light light)
{
this.screen = screen;
this.dvd = dvd;
this.sound = sound;
this.light = light;
} public void WatchMovie()
{
Console.WriteLine("开始播放电影......");
screen.Down();
dvd.PlayDVD();
sound.TurnOn();
light.TurnOff();
}
}

由于其他类比较简单就是一个打印输出,我就不列出来了,还有关闭方法同理也很简单就实现了。

还是测试一下效果:

外观模式定义

外观模式:提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。

外观模式遵循了一个设计原则

最少知识原则:之和你的密友谈话。

这个原则希望我们在设计中,不要让太多的类耦合在一起,免得修改系统中一部分,会影响其他部分。而外观模式让用户不用关心全部子系统组件,让客户变得简单有弹性。我们可以在不影响客户的情况下升级外观模式里的组件,而客户只有一个朋友,也就是外观模式。

三、适配器模式与外观模式区别

从上面例子我们也许会觉得适配器和外观模式之间的差异在于:适配器包装一个类,而外观可以代表许多类

但是实际它们的本质和作用并不是在于包装多少类,适配器模式将一个或多个接口变成客户期望的一个接口,我们一般适配一个类,但是特殊需求也可以适配多个类来提供一个接口。类是地,一个外观也可以只争对一个复杂接口的类提供简化接口。两中模式的差异在于他们的意图。适配器模式意图是将接口装换成不同接口,外观的意图是简化接口。

Head First设计模式——适配器和外观模式的更多相关文章

  1. Java设计模式之《外观模式》及应用场景

    原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/6484128.html 1.外观模式简介 外观模式,一般用在子系统与访问之间,用于对访问屏蔽复 ...

  2. iOS开发-适配器和外观模式

    适配器模式,属于结构型模式,其主要作用是将一个类的接口转换成客户希望的另外一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作.适配器模式有对象适配器和类适配器两种,类适配器模 ...

  3. c#设计模式之:外观模式(Facade)

    一.引言 在软件开发过程中,客户端程序经常会与复杂系统的内部子系统进行耦合,从而导致客户端程序随着子系统的变化而变化,然而为了将复杂系统的内部子系统与客户端之间的依赖解耦,从而就有了外观模式,也称作 ...

  4. Head First 设计模式 --7 适配器模式 外观模式

    适配器模式:将一个类东街口转换成客户期望的另一个接口.适配器让原本接口不兼容的类可以合作无间. 适配器模式有两种,对象适配器和类的适配器.先看一下对象适配器. 还是看最开始鸭子的例子,如果此时鸭子不够 ...

  5. PHP设计模式之:外观模式

    外观模式: 外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用: 外观模式又称为门面模 ...

  6. C#设计模式之十一外观模式(Facade)【结构型】

    一.引言 快12点半了,要开始今天的写作了.很快,转眼设计模式已经写了十个了,今天我们要讲[结构型]设计模式的第五个模式,该模式是[外观模式],英文名称是:Facade Pattern.我们先从名字上 ...

  7. 设计模式学习心得<外观模式 Facade>

    外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性. 这种模式涉及 ...

  8. C#设计模式之十外观模式(Facade Pattern)【结构型】

    一.引言 快12点半了,要开始今天的写作了.很快,转眼设计模式已经写了十个了,今天我们要讲[结构型]设计模式的第五个模式,该模式是[外观模式],英文名称是:Facade Pattern.我们先从名字上 ...

  9. 设计模式のFacadePattern(外观模式)----结构模式

    一.产生背景 外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性. ...

随机推荐

  1. Java描述设计模式(16):代理模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 在电商高速发展的今天,快递的数量十分庞大,甚至出现了快递代理行业,简单的说就是快递的主人没有时间收快递,会指定一个 ...

  2. 面试又被 Java 基础难住了?推荐你看看这篇文章。

    本文已经收录自 JavaGuide (59k+ Star):[Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识. 1. 面向对象和面向过程的区别 面向过程 :面向过程性能比面 ...

  3. 使用C++代码打印数字正方形

    使用C++代码打印数字正方形 作为一名初学者,最近在跟着网课学习C++程序设计基础.在学习过程中遇到了一些习题,我根据自己的理解和思路写了一些代码实现,算是对自己学习过程的一个记录,也希望可以对别人有 ...

  4. fenby C语言 P18

    #include <stdio.h> int main(){ int i; for(i=1;i<=15;i++) { if((i%2==1)) { printf("%d\n ...

  5. Linux 操作点滴

    1. 查找文件内容 find -type f -name '*' | xargs grep '' 2. 查看所有环境变量 env 3. so动态库文件查找路径:/lib    /usr/lib   / ...

  6. Bash shell类型

    登录shell(需要密码) 正常通过某一个终端来登录,需要输入用户名和密码. 使用su - username    使用su -l username 非登录shell(不需要密码) su userna ...

  7. 学习笔记16_页面缓存/进程外Session

    *页面缓存:适用于访问量较高的网站 <%@OutputCache Duration="15"//缓存15秒  VaryByParam='*' //请求的任何一处发生改变,缓存 ...

  8. 深度学习tensorflow实战笔记(1)全连接神经网络(FCN)训练自己的数据(从txt文件中读取)

    1.准备数据 把数据放进txt文件中(数据量大的话,就写一段程序自己把数据自动的写入txt文件中,任何语言都能实现),数据之间用逗号隔开,最后一列标注数据的标签(用于分类),比如0,1.每一行表示一个 ...

  9. $color$有色图

    不想看题解的请速撤离 为防被骂灌输题解,撤离缓冲区 这里没字 $Ploya$神题一道,所以我自己做不出来,颓了一部分题解. 由于理(颓题)解不(没)深(脸)中途又拿了$std$对拍(输出中间结果并qj ...

  10. Apache+Tomcat负载均衡

    参考:http://www.cnblogs.com/fly_binbin/p/3881207.html 反向代理负载均衡 (Apache2+Tomcat7/8)  使用代理服务器可以将请求转发给内部的 ...