《API Design for C++》读书笔记(二)

2. 观察者模式:

       对象维护一个它所依赖的对象(观察者)列表, 并通过调用观察者的方法通知观察者.  详细见第3章.

3. 通知:

      回调和观察者模式适用于特定的任务,它们的使用机制通常定义在执行实际回调的对象中。一个替代的解决方案是,在系统中不连通的部分之间构建集中发送通知机制或事件。发送者事先不需要知道接收者,这样可以降低发送者和接收者之间的耦合度。虽然通知机制有好几种,但是最流行的是信号和槽(signals and slots ).

      Qt, Boost的boost::signals和boost::signals2库.

      1个信号可对应多个槽,  当信号被调用/发出时,所有对应的槽都会被调用. 如下面的使用了boost::signal的:

class MySlot {
public:
   void operator()() const {
          std::cout << "MySlot called!"<< std::endl ;
   }
};
//创建MySlot类的一个实例 
MySlot slot;
//创建一个没有参数且返回值为空的信号
boost::signal<void ()> signal;
//连接槽和信号
signal.connect(slot);
//发出信号从而调用所有的槽
signa1();//创建MySlot类的一个实例 
MySlot slot;
//创建一个没有参数且返回值为空的信号
boost::signal<void ()> signal;
//连接槽和信号
signal.connect(slot);
//发出信号从而调用所有的槽
signa1();

第三章   模式

      设计模式是针对软件设计问题的通用解决方案.    大致分3类: 创建型 ,结构型, 行为型. 

      创建型模式        

         抽象工厂模式         创建一组相关的工厂
          建造者模式            将复杂对象的构建与表示分离
          工厂方法模式         将类的实例化推迟到子类中
          原型模式               指定类的原型实例,克隆该实例可以生成新的对象
          单例模式               确保类只有一个实例

      结构型模式

         适配器模式         将类的接口转换为另一种接口
          桥接模式            将抽象部分与它的实现部分分离,使它们都可以独立地变化
          组合模式            将对象组合成树型结构,表示“部分一整体”的层次结构
          装饰模式            动态地给一个对象添加一些额外的行为
          外观模式            为子系统中的一组接口提供统一的高层次接口
          享元模式            利用共享技术高效地支持大量细粒度的对象
          代理模式            提供另一个对象的替代物或占位符,以便控制对该对象的访问

     行为模式

          职责链模式       使多个接收者对象有机会处理来自发送者对象的请求
           命令模式          将请求或操作封装成对象,并支持可撤销的操作
           解释器模式      指定如何对某种语言的语句进行表示和判断
           迭代器模式      提供一种顺序访问某种聚合对象元素的途径
           中介者模式      定义一个中介对象,用于封装一组对象的交互
          备忘录模式       捕获对象的内部状态,以便将来可将该对象恢复到保存的状态
          观察者模式       定义对象间的一种一对多的依赖关系,当对象的状态发生改变时,所有依赖它的对象都将得到通知
          状态模式           当对象内部状态改变时,对象看起来好像修改了它所属的类
          策略模式           定义一组算法并封装毎个算法,使它们在运行时可以相互替换
          模板方法模式    定义某操作中算法的框架,将其中一些步骤推迟到子类中
          访问者模式       表述对某对象结构的元素所执行的操作

     C++惯用法:

  • Pimpl惯用法,该技巧支持在公有接口中完全隐藏内部细节。从本质上讲,它支持将私有的成员数据和方法转移到.cpp文件中。因此,Pimpl惯用法是构建接口和实现恰当分离的API的不可或缺的工具。
  • 单例和工厂方法。这是两种十分常见的构建型设计模式,深人理解是有益的。如果要确保只创建一个对象实例,那么单例模式很有用。在C++中单例的实现需要一些技巧,包括初始化 和多线程问题。工厂方法提供了创建对象实例的通用方法,它是隐藏派生类实现细节的好办法。
  • 代理、适配器和外观。这几种结构型模式提供了在现有的不兼容接口或遗留接口上封装API 的各种途径。编写API的常见整体目标是:改善一些设计拙劣的代码的接口。代理和适配器模式提供了从新类到现有类的一对一映射,而外观则为一大组类提供了简化接口。
  • 观察者。该行为型模式可以用来减少类之间的直接依赖。它通过一个类(观察者)在另一个类(主体)中注册通知的方式,使得概念上不相关的类相互通信。就其自身而言,该模式对设计松耦合的API至关重要。

3.1  Pimpl惯用法:

        Pimpl这个术语,将其作为“pointer to implementation”(指向实现的指针)的缩写.避免在头文件中暴露私有细节.

       将所有私有成员隐藏在cpp文件中,这样就不再需要包含任何繁琐的平台相关项.Pimpl惯用法将所有私有成员放置在一个类(或结构体)中,这个类在头文件中前置声明,在.cpp文件中定义,以此达到这一目的。

3.1.1  使用Pimpl:

     下面举例说明,考虑以下“自动定时器” API。它是一个具名对象,当被销毁时打印出其生存时间。

// autotimer.h 
#ifdef _WIN32 
#include <windows.h> 
#else
#include <sys/time.h>
#endif
#include <string>

class AutoTimer
{
public:
    ///使用易于理解的名字创建新定时器
    explicit AutoTimer (const std::string &name);
    ///在销毁时,定时器报告生存时间 
    ~AutoTimer();
private:
    //返回对象已经存在了多长时间
    double GetElapsed() const;
    std::string mName;
#ifdef _WIN32
    DWORD mStartTime;
#else
    struct timeval mStartTime: 
#endif
};

       上面的代码包含之前描述过的问题: 暴露了不同平台上存储的底层细节, 未隐藏私有成员.

       重构为:       

// autotimer.h 
#include 〈string〉

class AutoTimer 
{
public:
    explicit AutoTimer(const std::string &name); 
    ~AutoTimer();
private:
    class Impl; 
    Impl *mImpl ;//所有私有成员必须通过mImpl指针访问
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值