《现代软件设计技术PPT课件》由会员分享,可在线阅读,更多相关《现代软件设计技术PPT课件(36页珍藏版)》请在金锄头文库上搜索。
1、现代软件设计技术潘爱民2003-12-26内容Generic Programming构造框架(framework)的技术构造可重用类库的技术Generic programming思想:“通过参数化技术达到重用的目的(reuse through parameterization)”,使得组件更容易被定制。实现静态配置代码,从而获得很高的效率。 Generic Programming可以消除类型和算法之间本来不必要的相依性STL是成功的generic programming典型generic programming限制代码产生的方式:用实体类型代替类型参数,使这些预先编制好的代码模型成为真正的代码
2、,无法产生完全新的代码。相关的programmingAspect-Oriented Programming (AOP) An aspect is a modular unit that cross-cuts the structure of other modular units Aspects exist in both design and implementation. A design aspect is a modular unit of the design that cross-cuts the structure of other parts of the design. A
3、program or code aspect is a modular unit of the program that cross-cuts other modular units of the program. 把问题分解为功能单元(组件)和aspect在AOP系统中,组件和aspects(交织)组合起来得到一个系统的具体实现。交织组合既可以在compile-time,也可以在runtimeAOSD, 参考:http:/generative programmingGenerative Programming 建立起一族软件系统的模型,在特定的要求下,利用一些基本的、可重用的组件,通过配置,
4、能够自动根据需要产生一个高度定制和优化的软件系统实例一些原则用参数化技术来概括出差异性对于相依性和交互进行分析和建模通过静态链接(compile-time)消除不必要的开销,以及执行与特定领域相关的优化将问题空间和方案空间分离,通过配置建立两者的映射关系Separation of concerns: borrowed from AOP特点Generative Programming涉及到软件开发过程的各个阶段与Domain Engineering结合A Model-Based Approach:Active LibrariesC+ Generic ProgrammingTemplate技术使C
5、+成为two-level languagemetaprogram从科学计算用途-一般性的抽象,即generic programming对于编译器代码产生、优化在编译时刻,实现静态绑定 partial evaluation对于库开发人员Active libraries,提供一种抽象的功能,并且控制优化过程许多技术,如policy(traits)、编译时刻计算功能对于应用开发人员定制template class或者template functionC+ Generic Programming(续)设计思想编译时刻程序设计,类似于logic-programming即,在compile-time让编译
6、器完成一些功能,例如静态的计算功能if/else,loop,switch对type进行一些基本的逻辑操作(编程)保证类型安全宁可要compile-time error,也不要runtime error尽可能地泛化 抽象性跟传统的设计方法结合起来,比如利用patternsTemplate基础 class templatetemplateclass Array public:T& operator(size_t n) if (n =MAX_ELEMS) throw Out of bounds! ;return m_rgn;protected:T m_rgMAX_ELEMS;使用:Array a1;
7、Array a2;Template基础 模板特化template specializationtemplateclass Array public:char& operator(size_t n) if (n =256) throw Out of bounds!;return m_szn;bool operator= (const Array& rhs) return strcmp(m_sz, ) = 0;protected:char m_sz256;Template基础 部分模板特化 partial template specializationtemplateclass Array pub
8、lic:T& operator(size_t n) if (n =MAX_ELEMS) throw Out of bounds!;return m_szn;bool operator= (const Array& rhs) return strcmp(m_sz, ) = 0;protected:T m_szMAX_ELEMS;*Visual C+ 6不支持部分模板特化Template基础 函数模板function templatetemplate void Swap(T &a, T&b) T temp = a ; a = b; b = temp;template T& min(T& a, T&
9、 b) return a b ? a : b; 模板参数,compile-time起作用函数参数,runtime起作用Template基础 函数对象泛化generalized functors(function objects)functor:重载了operator()的C+对象,扩展了函数指针的概念,可以增加内部状态,可以被当作对象来传递,具有值语义(value semantic)。它可以是template class,也可以不是template class Functorpublic :ResultType operator()();/ other member functionpriva
10、te :/ implementation;用法:Functor MyFunctor(val1);int Result = MyFunctor();Template技术 代替runtime的if/else/ Class declarationstemplateclass ConditionProcess ;class ConditionProcess public: static inline void f() statement1; / true case;class ConditionProcess public: static inline void f() statement2; / f
11、alse case;/ Replacement for if/else statement:ConditionProcess :f();if (condition) statement1;else statement2;Compile-time能够确定condition的值Template技术 代替runtime的switch/ Class declarationstemplateclass SwitchProcess public: static inline void f() default-statement; ;class SwitchProcess public: static in
12、line void f() statement1; ;class SwitchProcess public: static inline void f() statement2; ;/ Replacement for switch(i) statementSwitchProcess :f();int i;switch(i) case value1: statement1; break; case value2: statement2; break; default: default-statement; break;Template技术 代替runtime的do循环templateclass
13、DoProcess private: enum go = (I-1) != 0 ;public: static inline void f() statement; DoProcess :f(); ;/ Specialization provides base case for recursionclass DoProcess public: static inline void f() ;/ Equivalent loop codeDoProcess :f();int i = N;do statement; while (-i 0);Template技术 代替runtime的临时变量temp
14、lateclass countBits enum bit3 = (N & 0x08) ? 1 : 0, bit2 = (N & 0x04) ? 1 : 0, bit1 = (N & 0x02) ? 1 : 0, bit0 = (N & 0x01) ? 1 : 0 ;public: enum nbits = bit0+bit1+bit2+bit3 ; ;int i = countBits:nbits;int countBits(int N) int bit3 = (N & 0x08) ? 1 : 0, bit2 = (N & 0x04) ? 1 : 0, bit1 = (N & 0x02) ?
15、1 : 0, bit0 = (N & 0x01) ? 1 : 0; return bit0+bit1+bit2+bit3;int i = countBits(13);Template技术 计算 Compile-time functions一般原则:局部变量用enum类型循环转化为递归,结束条件为一个特化版本也可以是多重循环,需要用到部分特化特性条件分支用模板特化解决效果:以类型为基础,实现各种操作例如sin x = x - x3/3! + x5/5! - x7/7! + 在编译时刻求pow(x,y),即x的y次方Template技术 计算pow(x,y) templatestruct ctim
16、e_pow enum result = X*ctime_pow:result ;templatestruct ctime_powenum result = 1;用法:const int z = ctime_pow:result;Trait技术定义一些“函数”,这些函数的参数和返回值都是类型(type),而不是数据(data)例如:对于一个数组类,它的元素类型和平均数的类型不一定相同,可以用一个trait class来建立这种映射关系对应关系Average_type(T) - TAverage_type(int) - floatTrait的使用:Average的实现Partial evaluat
17、ion一个程序的计算分为两个部分静态计算:在编译时刻执行动态计算:在运行时刻执行例如,计算立方体的体积Template技术 模板类作为基类某种程度上可以代替模板特化templateclass String : public Array public :/ additional functionalitybool operator=(const String& rhs) return strcmp(m_rg, ) =0;Template技术 以模板参数作为基类允许用户把自己的类插入到类层次的中间用户提供基类,类库使用基类templateclass Deriving : public Base C
18、+ as a two-level language将type当作first-class value来对待例如一种做法: 下面的句子typedef T T_average;相当于typedef T_average = T;实现了类型的赋值Template技术:动态绑定 模拟虚函数多态性templateclass Array public :virtual int Compare(const Array&rhs)=0;bool operator(const Array& rhs) return this-Compare(rhs) (const Array& rhs) return this-Com
19、pare(rhs) 0; bool operator=(const Array& rhs) return this-Compare(rhs) = 0; templateclass Array public :.bool operator(const Array& rhs) return static_cast(this)-Compare(rhs) (const Array& rhs) return static_cast(this)-Compare(rhs) 0; bool operator=(const Array& rhs) return static_cast(this)-Compare
20、(rhs) = 0; framework领域工程单个系统 一类系统有较强的抽象能力组件库提供定制功能,允许开发人员对于框架主体部分进行修改不同层次上的framework基于二进制代码的framework,例如MMC基于源代码的framework,例如MFC基于二进制的framework接口:为应用中的组件提供二进制接口以对象形式封装以功能为单位粒度大而全的接口小型接口,允许动态发现新的接口通信模型用户组件与框架进行通信用户组件之间如何通信?通过框架传递信息通过框架建立直通模型基于源代码的framework接口:一般为抽象类,用户提供虚函数的实现,并注册到主框架中用户定制的余地比较大通信模型用户
21、组件与框架进行通信用户组件之间容易建立起直通途径从派生类传播类型到基类的一种模式意图:基类有时需要根据子类的类型执行一些功能,而基类又不可能直接得到子类的静态类型这对于generic programming非常重要,因为编译器要靠静态类型来实例化模板(函数或者类)解决方案用虚函数不能解决问题 runtime多态性在子类中插入一个函数,由该函数调用模板函数或者模板类,或者该函数调用基类中的模板成员函数仅对基于源代码的framework适用Framework举例为报社提供一套frameworkSnap-In管理器FrameSiteFrameSiteFrameSiteSnapIn对象SnapIn对象
22、SnapIn对象Security管理器Database管理器UI管理器SnapIn仓库IFrameSiteISnapInfoSnapIn DLLSnapIn DLLSnapIn DLL可重用类库的设计(一)在所有的系统设计中,可重用类库的设计是难度比较大的,要做到:使用:灵活性和易用性功能:广泛性和效率经验非常重要实现同样的功能会有许多不同的道路,如何选择?效果怎么样?类库的基础是否使用其他的类库?是否使用特殊的平台和编译环境?参考成功的类库起点要高可重用类库的设计(二)接口的设计这是类库的关键,会影响到类库的使用接口的类型:C/C+大而全的接口并不理想接口的语义一定要清晰facade模式内存
23、管理保证内存分配和释放的一致性使用要方便out参数的资源由谁来申请?谁知道size?是否使用自定义的内存分配器,例如针对小对象的分配器可重用类库的设计(三)使用各种模式模式是经验,成功的典范policy模式允许使用者定制类结构型模式有助于建立起更加合理的结构模型,而不至于层次错综复杂行为型模式有助于各个类之间有更好的协作模型创建型模式可以提供各种合理的创建机制模板类库的特殊性利用模板类型实现compile-time的预处理熟悉编译器的特性控制模板生成代码可重用类库的设计(四)行为前置和延后在基类中提供缺省的实现纯虚函数 强制子类提供实现利用functor或者函数指针要求(必须)子类调用父类的实
24、现用宏来封装代码代码风格类库的优化优化需要用到内部知识,是否暴露这些知识允许使用者用policy进行配置,用不同的实现配置类类似于policy的思想,在细节点上用开关进行控制可重用类库的设计(五)类库的调试类库内部调试,使用assert支持类库的测试比应用系统的测试更加严格类库的发行是否提供源代码?文档编译设置可重用类库的设计(六)举例:MFC/ATLMFC同时也具有源代码框架的结构传统意义上的C+类库,对Win32进行了封装以便于使用为主要目标,优化较少用到了许多patterns,吻合Windows应用模式涉及到许多类库设计技术与Wizard结合产生基本代码ATL用到了generic programming中许多新的技术模板技术优化比较突出课程总结C+基础COM基础COM扩展COM+Design Patterns软件设计技术