深入解析设计模式中的适配器模式在C++中的运用

适配器模式属于结构型的设计模式,它是结构型设计模式之首(用的最多的结构型设计模式)。
适配器设计模式也并不复杂,适配器它是主要作用是将一个类的接口转换成客户希望的另外一个接口这样使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。适配器模式有两种:1.类的适配器 2.对象适配器,对象适配器更多一些。

示例:比如你在网上买了一个手机,但是买家给你发回来了一个3接头的充电器,但是恰好你又没有3接头的插槽,只有2个接口的插槽,于是你很直然地便会想到去找你个3接口转两接口的转换器。简单的分析下这个转换器便是我们这里的适配器Adapter。三相插头便是我们要适配的Adaptee,两相插类适配器-----在我看来C++的类适配器的用多重继承实现,并提供适配后的接口。

这是你的三相插头

class ThreePhaseOutlet
{
public:
  void doThreePhasePlugin()
  {
    cout<<"三相插头强势插入!"<<endl;
  }
};

这是你想要的两相插头

class TwoPhaseOutlet
{
public:
  virtual void doPlugin() = 0;
}; 

然后你将需要找到一个转接头,将三相插头转换为“两相插头”

class OutletConvertor: public TwoPhaseOutlet,public ThreePhaseOutlet
{
public:
  void doPlugin()
  {
    doConvertor();
    doThreePhasePlugin();
  }
    void doConvertor()
  {
    cout<<"三相插头转为两厢插头!"<<endl;
  }
};

现在你可以强势插入两相的插口了。

TwoPhaseOutlet* outlet = new OutletConvertor();
outlet->doPlugin();

对象适配器模式-----对象适配器是将需要适配的对象进行包装然后提供适配后的接口。

对象适配器的 三相插口和转接头的代码和上面一致。只是整合步骤不一致

class OutletConvertor : public TwoPhaseOutlet
{
public:
  void doPlugin()
  {
    doConvertor();
    m_out.doThreePhasePlugin();
  }
  void doConvertor()
  {
    cout<<"三相插头转为两厢插头!"<<endl;
  }
  ThreePhaseOutlet m_out;
};

对象适配器相比类适配器来说更加灵活,他可以选择性适配自己想适配的对象。例如我们下面把代码改成这样,你也许就会明白为什么我这样说:

class OutletConvertor : public TwoPhaseOutlet
{
public:
  OutletConvertor(ThreePhaseOutlet out)
  {
    m_out = out;
  }
  void doPlugin()
  {
    doConvertor();
    m_out.doThreePhasePlugin();
  }
  void doConvertor()
  {
    cout<<"三相插头转为两厢插头!"<<endl;
  }
  ThreePhaseOutlet m_out;
};

我们在构造的时候将具体需要适配的适配对象传入,这样便可以根据传入不同的对象,从而对该对象进行适配。而类适配器却无法选择对象,他是对整个类进行适配。也就是把所有的三相插口全部转换为两相的,而不是针对某一个。

在以下各种情况下使用适配器模式:

1、 系统需要使用现有的类,而此类的接口不符合系统的需要。
2、 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。这些源类不一定有很复杂的接口。
3、 (对对象适配器而言)在设计里,需要改变多个已有子类的接口,如果使用类的适配器模式,就要针对每一个子类做一个适配器,而这不太实际。

Adapter模式在实现时有以下这些值得注意的地方:

1、 目标接口可以省略,模式发生退化。但这种做法看似平庸而并不平庸,它可以使Adaptee不必实现不需要的方法(可以参考Default Adapter模式)。其表现形式就是父类实现缺省方法,而子类只需实现自己独特的方法。这有些像模板(Template)模式。
2、 适配器类可以是抽象类。
3、 带参数的适配器模式。使用这种办法,适配器类可以根据参数返还一个合适的实例给客户端。

(0)

相关推荐

  • 详解设计模式中的中介者模式在C++编程中的运用

    作用:用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 结构图如下: Colleage抽象同事类,而ConcreteColleage是具体同时类,每个具体同事只知道自己的行为,而不了解其他同事类的情况,但它们却都认识中介者对象,Mediator是抽象中介者,定义了同事对象到中介者对象的接口,ConcreteMediator是具体中介者对象,实现抽象类的方法,它需要知道所有具体同事类,并从具体同事接受消息,向具体同事对象

  • 设计模式中的备忘录模式解析及相关C++实例应用

    备忘录模式旨在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态.在命令模式中,备忘录模式经常还经常被用来维护可以撤销(Undo)操作的状态. 类图: Originator:负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态.Originator可根据需要决定Memento存储Originator的哪些内部状态. Memento:负责存储Originator对象的内部状态,并可防止Origin

  • 解析C++编程中如何使用设计模式中的状态模式结构

    作用:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. UML图如下: State类,抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为. ConcreteState类,具体状态,每一个子类实现一个与Context的一个状态相关的行为. Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态. 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况.把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把

  • 详解C++设计模式编程中对访问者模式的运用

    访问者模式(visitor),表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作.访问者模式适用于数据结构相对稳定的系统.它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化.访问者模式的目的是要把处理从数据结构分离出来.很多系统可以按照算法和数据结构分开,如果这样的系统有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就是比较合适的,因为访问者模式使得算法操作的增加变得容易.反之,如果这样的系统的数据结

  • 详解C++设计模式编程中责任链模式的应用

    职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 其思想很简单,比如考虑员工要求加薪.公司的管理者一共有三级,总经理.总监.经理,如果一个员工要求加薪,应该向主管的经理申请,如果加薪的数量在经理的职权内,那么经理可以直接批准,否则将申请上交给总监.总监的处理方式也一样,总经理可以处理所有请求.这就是典型的职责链模式,请求的处理形成了一条链,直到有一个对象处理请求.给出这个例子的UML图.

  • 实例讲解C++设计模式编程中State状态模式的运用场景

    State模式允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类. 在面向对象系统的开发和设计过程,经常会遇到一种情况就是需求变更(Requirement Changing),经常我们做好的一个设计.实现了一个系统原型,咱们的客户又会有了新的需求.我们又因此不得不去修改已有的设计,最常见就是解决方案就是给已经设计.实现好的类添加新的方法去实现客户新的需求,这样就陷入了设计变更的梦魇:不停地打补丁,其带来的后果就是设计根本就不可能封闭.编译永远都是整个系统代码. 访问者模式则提

  • C++设计模式编程之Flyweight享元模式结构详解

    由遇到的问题引出享元模式: 在面向对象系统的设计何实现中,创建对象是最为常见的操作.这里面就有一个问题:如果一个应用程序使用了太多的对象,就会造成很大的存储开销.特别是对于大量轻量级(细粒度)的对象,比如在文档编辑器的设计过程中,我们如果为没有字母创建一个对象的话,系统可能会因为大量的对象而造成存储开销的浪费.例如一个字母"a"在文档中出现了100000 次,而实际上我们可以让这一万个字母"a"共享一个对象,当然因为在不同的位置可能字母"a"有不

  • 深入解析C++设计模式编程中解释器模式的运用

    解释器模式(interpreter),给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 解释器模式需要解决的是,如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子.这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题.当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式.用了解释器模式,就意味着可以很容易地改变和扩展文法,因为该模式使用类来表示文法规则,

  • C++设计模式编程中使用Bridge桥接模式的完全攻略

    桥接模式将抽象(Abstraction)与实现(Implementation)分离,使得二者可以独立地变化. 桥接模式典型的结构图为: 在桥接模式的结构图中可以看到,系统被分为两个相对独立的部分,左边是抽象部分,右边是实现部分,这两个部分可以互相独立地进行修改:例如上面问题中的客户需求变化,当用户需求需要从 Abstraction 派生一个具体子类时候,并不需要像上面通过继承方式实现时候需要添加子类 A1 和 A2 了.另外当上面问题中由于算法添加也只用改变右边实现(添加一个具体化子类),而右边

  • 详解设计模式中的Command命令模式及相关C++实现

    命令模式的作用是将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤销的操作. 由于"行为请求者"与"行为实现者"的紧耦合,使用命令模式,可以对请求排队或记录请求日志,以及支持可撤销的操作. 命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开. Command模式关键就是讲一个请求封装到一个类中(Command),再提供处理对象(Receiver),最后Command命令由Invoker激活.另外,我们

随机推荐