zoukankan      html  css  js  c++  java
  • Head First设计模式——适配器和外观模式

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

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

    另外装饰模式可以看我的另一篇博文→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();
            }
        }
    

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

    还是测试一下效果:

    外观模式定义

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

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

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

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

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

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

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

  • 相关阅读:
    vue项目中使用axios上传图片等文件
    es6入门set和map
    自定义组件实现双向数据绑定
    vue watch详细用法
    bind,call,applay的区别
    前端路由两种模式:hash、history
    jsonp封装成promise
    正则元字符理解2
    webpack配置
    vuex的几个细节
  • 原文地址:https://www.cnblogs.com/SunSpring/p/11946631.html
Copyright © 2011-2022 走看看