首页计算机计算机软件设计模式 04 第三部分 结构型设计模式.pptx

04 第三部分 结构型设计模式.pptx

页数:33页文件大小:192.3 KB来源: 设计模式ppt课件

本课件讲解结构型设计模式,说明桥接模式如何分离接口与实现、适配器模式如何转换已有接口、合成模式如何一致地处理树形结构,以及门面模式如何为子系统提供统一入口。

第三部分结构型设计模式目录,列出桥接、适配器、合成、门面、装饰等模式
桥接模式引入页,指出类的变化存在接口、实现与属性三个不同方向
单个方向变化的适应说明,使用组合或继承方式都较容易实现
查看本课件的文字版(共 33 页,供检索与复制)

第1页:第三部分 结构型设计模式

第三部分结构型设计模式

  • 桥接模式(Bridge Pattern)
  • 适配器模式(Adpter Pattern)
  • 合成模式(Compsite Pattern)
  • 门面模式(Facade Pattern)
  • 装饰模式(Decorator Pattern)
  • 代理模式(Proxy Pattern)
  • 享元模式(Flyweight Pattern)

第2页:3.1 桥接模式

3.1桥接模式(Bridge Pattern)

class A{ public: virtual ~A(); virtual void f( ); virtual void g( ); private: intx; inty; };变化的三个方向:1)接口的变化2)实现的变化3)属性的变化(本质上,还是实现的变化)

第3页:适应单个方向的变化

适应单个方向的变化

  • 容易
  • 组合和继承方式均可

第4页:适应接口变化的方法

适应接口变化方法class A{public:virtual ~A();virtual void f( );virtual void g( );protected :intx;inty;};class NewA:public A{public:virtual ~NewA( );virtual void h( );};class NewA{public:NewA(A * oldA):pa(oldA) { }virtual ~NewA( );virtual void f( ) { pa->f( ); }virtual void g( ) { pa->g( ); }virtual void h( );private:A* pa;};

第5页:适应实现变化的方法

适应实现变化方法class A{public:virtual ~A();virtual void f( );virtual void g( );protected:intx;inty;};class NewA:public A {public:virtual ~NewA( );virtual void f( ) {}};class NewA {public:NewA(A * oldA):pa(oldA) { }virtual ~NewA( );virtual void f( ) {}virtual void g( ) { pa->g( ); }protected:A* pa;};class NewA {public:NewA(ImpF * f,ImpG * g):pf(f),pg(g) { }virtual ~NewA( );virtual void f( ) {pf->f( );}virtual void g( ) { pg->g( ); }private:ImpF * pf;ImpG * pg;};class ImpF {public:virtual ~ImpF( );vritual void f( )=0;};class ImpF1:public ImpF {public:virtual ~ImpF1( );vritual void f( ) { }};

第6页:两个方向同时变化的适应

两个方向同时变化的适应

  • 单一使用组合或继承的不足
  • 结合组合和继承的方式
  • 分离变化
  • 用组合关联两个方向的变化
  • 使单个方向的变化独立出来(独立变化)
  • 例

第7页:第一步:分离接口和实现

第一步:分离接口和实现classA {public:virutal ~A( );virtual void f( ) ;virtual void g( );};class ImpA {public:virtual ~ImpA();virtual void f( );virtual void g( );protected:intx;inty;};

第8页:第二步:组合连接接口和实现

第二步:用组合连接接口和实现classA {public:virutal ~A(ImpA * p):impA(p) {}virtual void f( ) { impA->f( ); }virtual void g( ) { impA->g( );}private:ImpA* impA;};class ImpA {public:virtual ~ImpA();virtual void f( );virtual void g( );protected:intx;inty;};

第9页:第三步:接口与实现独立变化

第三步:使接口和实现的变化独立classA {public:virutal ~A(ImpA * p):impA(p) {}virtual void f( ) { impA->f( ); }virtual void g( ) { impA->g( );}private:ImpA* impA;};class ImpA {public:virtual ~ImpA();virtual void f( );virtual void g( );protected:intx;inty;};classNewA:pubic A {public:virutal ~NewA(ImpA * p):A(p) {}virtual void h( ) { }};class ImpA1:public ImpA {public:virtual void f( ) { }};继承继承组合

第10页:桥接模式效果

3.1.2效果

  • 分离了接口及其实现
  • 使得各部分可独立变化、扩展
  • 可对客户隐藏实现部分
  • 也称Handle模式/Handle-Body模式

第11页:桥接模式结构

3.1.3结构

第12页:3.2 适配器模式

3.2适配器模式(Adapter Pattern)

  • 已有现成的两个类簇-Student和Teacher类簇;
  • 希望创建一些新的实例-具有学生的功能,但这些功能又用到教师的功能;
  • 例:

第13页:学生与教师的类定义

学生、教师class IStudent {public:virtual ~IStudent();virtual void上课( );virtual void休息( );};class Teacher {public:virtual ~Teacher( );virtual void授课();virtual void玩();};1.学生可有本科生、硕士研究生、博士研究生等;2.现增加一类在职学生----本身也是教师。3.这时,在职学生的上课就是教师的授课;4.怎么才能将教师,当做学生来使用呢?

第14页:接口不一致的问题

问题

  • 接口的不一致性
  • 原接口的不可更改性
  • 解决方式:
  • 类的适配器方式
  • 对象适配器方式

第15页:类的适配器模式

类的适配器模式class IStudent {public:virtual ~IStudent();virtual void上课( ) =0;virtual void休息( )= 0;};class Teacher {public:virtual ~Teacher( );virtual void授课();virtual void玩();};class在职学生: public IStudent, private Teacher {public:virtual ~在职学生();virtual void上课( ) {授课();}virtual void休息( ) {玩(); }};

第16页:对象适配器方式

对象适配器方式class IStudent {public:virtual ~IStudent();virtual void上课( ) =0;virtual void休息( )= 0;};class Teacher {public:virtual ~Teacher( );virtual void授课();virtual void玩();};class在职学生: public IStudent{public:在职学生(Teacher * t): tc(t) { }virtual ~在职学生();virtual void上课( ) { tc.授课();}virtual void休息( ) { tc.玩(); }private:Teacher *tc;};

第17页:适配器模式效果

3.2.2效果

  • 在不改变原有类的前提下,调整原有类的接口
  • 适用性:
  • 使用已有的类,但类的接口不符合需要;
  • 对象适配器,通常比类适配器更灵活;

第18页:类适配器结构

3.2.4类适配器结构

第19页:对象适配器结构

3.2.5对象适配器结构

第20页:3.3 合成模式

3.3合成模式(Compsite Pattern)一个树形结构:树枝树叶树枝树枝树叶树枝树叶树枝树枝树叶树枝树叶树枝树枝树叶

第21页:节点的关系表示

节点的关系表示

  • 根节点(特殊的树枝/叶子节点)
  • 树枝节点
  • 叶子节点是否有更一般化的表示呢?即不论哪种节点,访问的方法最好能一致些呢?

第22页:节点的一般化表示

一般化表示

第23页:子节点的管理

子节点的管理

  • AddChild(),RemoveChild( ),GetChild(int),GetChildren()等只对树枝节点有意义
  • 这些管理子节点的操作放哪个类里呢?
  • 放Node中(透明式)
  • 放BranchNode中(安全式)

第24页:透明式合成模式结构(1)

3.3.2透明式合成模式结构(1)

第25页:透明式合成模式结构(2)

透明式合成模式结构(2)

第26页:安全式合成模式

安全式合成模式

第27页:合成模式示例:集团公司

3.3.3例子

  • 一个集团公司:下设多个部门,如办公室、财务处、基建处、人事处等;同时还下设多个分公司,如北京分公司、广东分公司等;各分公司,也可以下设多个部门和多个分公司,如广东分公司,可能下设财务处、投标办、广州分公司、深圳分公司、珠海分公司等。

第28页:3.4 门面模式

3.4门面模式(Facade Pattern)一个子系统:内部有许多类,该子系统通过这些类和它们之间的交互作用,为客户提供相应的功能。

第29页:用户与子系统的交互问题

CBDA用户1用户21.用户必须清楚子系统中的各部分的职责;2.用户不关心子系统的实现,而只是应用子系统中的已有功能;3.用户的访问,通常是单向的;

第30页:引入门面后的结构

CBDA用户1用户2门户

第31页:门面模式结构

3.4.2结构Facade

第32页:门面模式效果

3.4.3效果

  • 对用户隐藏了系统的实现,易用;
  • 降低了Client与子系统之间的耦合;
  • 仍然可以直接与子系统内部交互;
  • 适用性:
  • 为复杂系统提供简单接口;
  • 为多个子系统提供统一的“门面”,保持子系统的独立变化性;
  • 便于构建层次化的系统;

第33页:门面模式示例:DirectX

3.4.4例DirectX:Direct3D、DirectInput、DirectMedia

顶部目录