Pattern-Oriented Software Architecture, Patterns for Concurrent and Networked Objects, Volume 2, 详细读书笔记 3

 
[实现]
本节描述实现Wrapper Facade模式包括的活动,这些活动可能会有多次迭代。为了节省篇幅,这里深度讨论了mutexes, condition variables, Sockets 和 threads 的Wrapper Facade,而使用Wrapper Facade的别的模式都只是简单的引用此实现过程,这些模式包括:Acceptor-Connector ,Strategized Locking , Thread-Specific Storage , 和 Monitor Object。
    1 在已有的底层API中识别出内聚抽象及API之间的关系。成熟的底层API的函数和数据结构定义了内聚的抽象,能清晰地映射到面向对象的类和方法中。(举了些例子,分析了如C这样的语言缺乏数据抽象,表达不清楚哪些API相互关联,因此需要此步骤……)
        (上面的日志实现例子中,mutex_lock() 和 mutex_unlock()都关联到 mutex,而socket(), bind(), listen()和 accept()则扮演网络相关角色)
[page 56]
    临时代码或piecemeal growth [FoYo99]的代码,可能会体现出很少(或根本没有)内聚抽象,如果有可能,这样的代码应该在实现Wrapper Facade之前重构[Opd92][FBBOR99]。
    2 将内聚的一组function聚集到Wrapper Facade类和方法中。(此活动屏蔽了底层细节……)。可分成5个子活动:
        1 创建内聚类。作为开始,我们为每组表示特定抽象的相关联的非面向对象API定义一个或多个Wrapper Facade,创建内聚类通常使用如下标准:
            - 将高内聚的函数和数据很并到独立的类中,尽量减小类之间的耦合性。(Examples of cohesive functions are those that manipulate common data structures, such as a Socket, a file, or a signal set [Ste98].)
            - 区分出底层函数和数据间公共和差异方面。(分别描述公共和差异方面应该涉及些什么。……)
        总之,如果原始API包括了大量相关连的函数,那就需要创建多个Wrapper Facade类去分别关注不同方面。
        2 将多个独立的函数合并为一个方法。(能保证一组底层函数能按合适的顺序运行。……)
        3 如有可能,实现自动创建和销毁操作。(大概说,很多程序中都需要创建数据,而用完后要释放数据,这种过程通常很容易出错。应该用某种自动的机制来解决此问题。……)
        4 确定非直接访问的层次。(因为Wrapper Facade需要调用底层API函数,采用inline的方式就没有性能损失,而采用多层调用方式则可以动态绑定方法,也更灵活……)
[page 57]
        5 决定在哪里封装特定平台的差异性。Wrapper Facade通常减小了应用程序代码中的平台差异性。虽然Wrapper Facade的方法实现会根据操作系统平台不同而不同,但是他们应该提供平台独立的统一接口。而特定平台的差异性可以通过条件编译或分离目录的方式封装起来:
            - 条件编译(Conditional compilation)(采用如#ifdef这样的条件编译指令……)
            - 分离目录(Separate directories)(将不同的平台的实现分放在不同目录,编译时根据配置读取不同的实现……)
        (在这段中,分析了根据Wrapper Facade接口和实现的改变频率来选则采用哪种平台差异性的封装方式,而且无论采用哪种策略,都应该是由Wrapper Facade的开发者来维护Wrapper Facade,而不应该加重应用程序的开发者的负担。……)
            (在例子中引入了Wrapper Facade用以简化日志服务器的实现。……)
            (在[page 58-65]中引入了很多日志服务器的实现代码……)
[page 65]
(blah...blah...)
    3 考虑允许受控的应用程序访问实现细节。采用Wrapper Facade的好处在于写程序的正确率高(不容易写错误的程序),程序可移植性强,如:socket使用指针来表示,还是用整数来表示,这种特定平台的、易错的实现细节都被Wrapper Facade屏蔽掉了。然而,设计者通常没有预料到,特别抽象、非常强的类型安全性实际上会妨碍程序员有效地使用Wrapper Facade,(?? This experience can be frustrating and may discourage programmers from leveraging other benefits of wrapper facades.)程序员会放弃使用Wrapper Facade带来的其他好处。
    要解决太抽象的问题,可以采用如AOP[KLM+97]一样的‘安全窗口(escape hatch)’机制或开放实现技术,这种设计可允许应用程序用受控的方式访问实现细节。
        (举了个SOCK_Stream例子,为了支持附加的原始的Socket Wrapper Facade没有提供的功能,引入了访问SOCKET句柄的方法,外部可以通过访问socket句柄就能实现附加功能。)
    因为安全窗口机制减弱了Wrapper Facade模式的可移植性,增加了潜在错误的可能性,抵消了Wrapper Facade所带来的好处,当然应该少用这种机制。如果应用程序在某小范围内重复使用特定的安全窗口,则也许表示应该在Wrapper Facade的公共接口中添加一个方法。Extension Interface模式描述了在不影响已有的客户端的前提下添加这种新方法的技术。
    4 开发错误处理机制。C语言方式的底层API通常采用返回值,或如errno这样的整数编码,将他们的错误返回给调用者,如果调用者不检查这种返回状态值,则这种技术是很容易出错的。
[page 66]
    异常(exception)处理机制是处理错误的更优雅的方式,很多程序语言,如:C++,java等,都将异常作为基础的错误报告机制,另外一些操作系统,如Win32[Sol98]也采用了异常处理机制。将异常处理作为基础的错误报告机制有一下优点:
        - 可扩展,(……)
        - 与正常处理流程解除耦和,(……)
        - 类型安全,(……)
    (举了一个异常的例子……)
    不幸的是wrapper facade类中的异常也有一些缺点:
[page 67]
        - 并不是被所有的程序语言支持。(……)
        - 各种语言中的异常实现不同,很难将不同语言实现的能抛出异常的组件集成起来。(……)
        - 异常处理导致了多条程序路径,使资源管理变得更复杂。(……)
        - 拙劣的异常实现将导致额外的空间或时间上的浪费,(……)
    (wrapper facade的缺点在封装核心层的驱动和底层操作系统API时尤其突出,……)
    5 定义相关的辅助类(可选)。将底层API封装到wrapper facade类之后,有可能创建其他的辅助类,进一步简化应用程序的开发,这些辅助类通常只有在将底层功能和他们相关的数据都封装到wrapper facade类中过后,才会显现出好处。
        (用Thread_Mutex举了个例子……)
[page 68]
(blah...blah...继续例子)

[例子解决方案]
    (将[例子]一节的代码采用wrapper facade进行封装过后,最终的代码示例)
[page 69-72]
    (都是例子代码)

[page 73]
[已知应用]
    MFC(Microsoft Foundation Classes)(……)
    ACE(……)
    Rogue Wave(……)
    ObjectSpace(……)
    JVM & Java类库(……)
    Simens REFORM(……)
    Books consisting of edited collections of papers.(……)

[page 74]
……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值