Head First 设计模式之适配器模式与外观模式

Head First设计模式之适配器模式与外观模式

前言:

之前讲过装饰者模式,将对象包装起来并赋予新的职责,这一章我们也会将对象进行包装,只不过是让它们看起来不像自己而像是别的东西。这样就可以在设计中将类的接口转化为想要的接口,以实现同的接口,此外还将讲述另一个模式,将对象包装起来以简化接口。

1.   适配器简介

1.1 面向对象的适配器

真实世界的适配器比如位于美式插头和欧式插座之间的交流电适配器。面向对象的适配器是什么呢?

面向对象的适配器是将一个接口转化成另一个接口,以符合客户的期望。

例如已有的一个软件系统,希望它能和一个新的厂商类库搭配使用,但是这个厂商设计出来的接口不同于旧的接口,而你又不想改变现有的代码,所以这个时候就需要一个适配器来完成现有系统和新的厂商类库的对接。

1.2 使用中的适配器

我们在策略模式里举例讲的鸭子。看一个简化版的示例。

1.2.1 鸭子接口
publicinterface Duck
    {
       void Quack();//鸭子叫
       void Fly();//鸭子飞
}
1.2.2 鸭子子类(绿头鸭)实现
publicclass MallardDuck:Duck
    {
        public void Quack()
        {
            Console.WriteLine(" Quack");
        }
        public void Fly()
        {
            Console.WriteLine(" Fly");
        }
}
1.2.3 新的禽类接口以及具体实现
publicinterface Turkey
    {
        void Gobble();//咯咯叫
       void Fly();//飞
}
publicclass WildTurkey : Turkey
    {
        public void Gobble()
        {
            Console.WriteLine(" GobbleGobble");
        }
        public void Fly()
        {
            Console.WriteLine(" I‘m flyinga short distance ");
        }
    }
1.2.4 适配器
publicclass TurkeyAdapter:Duck//实现想转换成的类型接口
    {
        Turkey turkey;
        public TurkeyAdapter(Turkey turkey)//取得适配器的对象引用,并利用构造得到这个引用
        {
            this.turkey = turkey;
        }

        public void Quack()//实现接口中的所有方法
        {
            turkey.Gobble();
        }

        public void Fly()
        {
            for(var i=0;i<5;i++)
            turkey.Fly();
        }
}
1.2.5 测试
MallardDuckduck = new MallardDuck();
            WildTurkey turkey = newWildTurkey();
            Duck turkeyAdapter = newTurkeyAdapter(turkey);

            Console.WriteLine(" The turkeysyas ...");
            turkey.Gobble();
            turkey.Fly();

            Console.WriteLine(" The Ducksays ...");
            turkeyAdapter.Quack();
            turkeyAdapter.Fly();

            Console.Read();

结果如下:

1.3 适配器模式解析

客户使用适配器的过程如下:

l  客户通过目标接口调用适配器的方法对适配器发出请求。

l  适配器使用被适配者接口把请求转化成被适配者的一个或多个调用接口。

l  客户接收到调用的结果。

2.   定义适配器模式

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

该模式可以通过创建适配器进行接口转换,让不兼容的接口变得兼容,让客户从实现的接口解耦。其类图如下:

该适配器充满了OO设计的原则:使用对象组合,以修改的接口包装被适配者。被是陪者的任何子类都可以搭配着适配器使用。该模式是把客户和接口绑定起来的,而非和实现绑定。

实际上有两种适配器:对象适配器和类适配器。类适配器通过多重继承来实现,而对象适配器利用组合的方式将请求传递给被适配者。

类适配器图:

3.   定义外观模式

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

外观模式允许我们让客户和子系统之间避免紧耦合。类图如下:

4.   最少知识原则

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

最少知识原则告诉我们要减少对象之间的交互。该原则希望在设计时,不要让太多的类耦合在一起,免得修改系统中的一部分,会影响到其他部分。

怎样避免让太多的类耦合在一起呢?主要有以下的方针:

就对象而言,在该对象的方法内,我们只应该调用属于以下范围的方法:

l  该对象本身

l  被当做方法的参数而传递进来的对象

l  此方法所创建或实例化的任何对象

l  对象的任何组件

如下示例:

(不要采用这个原则)从气象站取得了温度计对象,然后再从温度计对象取得问题

Publicfloat GetTemp()
{
   Thermometerthermometer=station.GetThermometer();
   return thermometer.GetTemperature();
}

(采用这个原则)我们在气象站中加进一个方法,用来向温度计请求温度。可以减少我们所依赖的类的数据。

Publicfloat GetTemp()
{
  Return station.GetTemperature();
}

5.   总结

l  当需要使用一个现有的类而其接口并不符合你的需要时,就需要使用适配器。

l  当需要简化并统一一个很大的接口或者一群负责的接口时,使用外观。

l  适配器改变接口以符合客户的期望。

l  外观将客户从一个复杂的子系统中解耦。

l  实现一个适配器的难易视目标接口的大小与复杂而定。

l  实现一个外观,需要将子系统组合进外观中,然后将工作委托给子系统执行。

l  适配器分为对象适配器和类适配器,类适配器需要多重继承。

l  可以为一个子系统实现一个以上的外观。

l  适配器将一个对象包装起来以改变其接口;装饰者将一个对象包装起来以增加新的行为和责任;而外观将一群对象“包装”起来以简化其接口。

时间: 2024-10-18 11:28:14

Head First 设计模式之适配器模式与外观模式的相关文章

设计模式之适配器模式与外观模式

适配器模式将一个类的接口,转换成客户期望的另一个接口.适配器让原本接口不兼容的类可以合作无间. 例子:火鸡变鸭子. 先定义一个鸭子接口. package cn.sp.test06; /** * 鸭子 * @author 2YSP * */ public interface Duck { //具备呱呱叫 和 飞行的能力 public void quack(); public void fly(); } package cn.sp.test06; /** * 绿头鸭是鸭子的子类 * @author

设计模式 之 适配器模式与外观模式

一.适配器模式: 适配器模式,简单的说就是“到什么山,唱什么歌 ”,即它解决的是不兼容.不匹配的问题.先来举个小例子:当我们要把一个三相插头插到一个二相插座中,我们应该怎么做呢?当然是去找一个三相转二相的适配器插座,在这个例子中,适配器插座的作用是为了改变插座的接口,满足三相插头的需要:同样的,在我们接下来要介绍的OO适配器模式中,适配器的作用是将一个接口转换成另一个接口,以满足客户的需要. 下面我们用代码来演示这个例子.我们先贴出PlugOfTwo和PlugOfThree两个接口,表示二相插座

Java经典23种设计模式之结构型模式(三)------附代理模式、适配器模式、外观模式区别

本文介绍7种结构型模式里的剩下两种:享元模式.代理模式. 一.享元模式FlyWeight 享元模式比较简单且重要,在很多场合都被用到,只不过封装起来了用户看不到.其概念:运用共享内存技术最大限度的支持大量细粒度的对象.这个概念给的有些抽象,说白了就是如果内存中存在某个对象A,如果再次需要使用对象A的时候如果内存中有A这个对象就直接使用它,不要再次new了.如果没有,则重新new一个.基于这个特点,享元模式使用时一般会给待访问对象传递一个Tag,用来标识这个对象,而且要同时使用抽象工厂的方法进行访

设计模式之代理模式、适配器模式和外观模式

编写基于另一组类的包装器接口是一项常见的API设计任务,例如,你的工作可能是维护一个大型的遗留代码库,相比重构所有代码,你更愿意审计一个新的 ,更简洁的API,以隐藏所有的底层遗留代码:或者你可能已经编写了一个C++API,后来需要给特定客户提供C接口:或者你的API用到了一个第三方依赖库,你想让客户直接使用此库,但是又不想将此库直接暴露给客户. 创建包装器API的潜在副作用是影响性能,这主要因为额外增加的一级间接寻址以及存储包装层次状态带来的开销.但就上面提到的那些情而言,这么做可以创建质量更

设计模式 8 —— 适配器和外观模式

设计模式目录: 设计模式 1 ——观察者模式 设计模式 2 —— 装饰者模式 设计模式 3 —— 迭代器和组合模式(迭代器) 设计模式 4 —— 迭代器和组合模式(组合) 设计模式 5 —— 工厂模式 设计模式 6 —— 单件模式 设计模式 7 —— 命令模式 设计模式 8 —— 适配器和外观模式 概述 第1部分 问题引入 第2部分 适配器模式定义 第3部分 对象和类的适配者 第4 部分 适配器模式与装饰者模式区别 第5 部分 外观模式 第1 部分 问题引入 OO适配器是什么,现实中到处都是.比

Java设计模式(五)外观模式 桥梁模式

(九)外观模式 外观模式为子系统提供一个接口,便于使用.解决了类与类之间关系的,外观模式将类之间的关系放在一个 Facade 类中,降低了类类之间的耦合度,该模式不涉及接口. class CPU { public void startup(){ System.out.println("cpu start"); } public void shutdown(){ System.out.println("cpu stop"); } } class Memory { pu

设计模式学习笔记之适配器模式、外观模式

适配器模式     将一个类的接口转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以合作无间. 通过创建适配器进行接口转换,让不兼容的接口变成兼容.这可以让客户从实现的接口解耦.如果在一段时间后,想要改变接口,适配器可以将改变的部分封装起来,客户就不必为了应对不同的接口 而每次跟着修改. 客户使用适配器的过程: 1.客户通过目标接口调用适配器的方法对适配器发出请求: 2.适配器使用被适配器接口把请求转换成被适配器的一个或多个调用接口: 3.客户端收到调用的结果,但并未察觉这一切是适配器在

《Head First 设计模式》之适配器模式与外观模式

适配器模式(Adapter) 适配器(adapter-pattern):将一个类的接口,转换成客户期望的另一个接口.适配器让原来接口不兼容的类可以合作无间.两种形式: 对象适配器(组合) 类适配器(多重继承):在Java中不能实现 外观(facade-pattern):提供了一个统一的接口,用来访问子系统中的一群接口.外观定义了一个高层接口,让子系统更容易使用. 原则 最少知识原则:只和你的密友谈话 要点: 当需要使用一个现有的类而其接口不符合需要时,使用适配器.适配器改变接口以符合客户期望.

[设计模式]适配器模式与外观模式

之前的装饰者模式,是将对象包装起来,赋予新的功能.适配器模式则是包装对象,使其接口看起来不像自己而是别的对象,就是将类的接口转换成想要的接口,以便实现不同的接口.而外观模式则是将对象包装起来以简化其接口. 适配器模式讲一个类的接口,转换成客户期望的另一个接口.适配器让原本接口不兼容的类可以合作无间. 外观模式提供了一个统一的接口,用来访问子系统中的一群接口.外观定义了一个高层接口,让子系统更容易使用.这个模式也表现了一个设计原则,最少知识原则.