您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
设计模式之外观模式和代理模式
 
作者 fengbingchun的博客,火龙果软件    发布于 2014-07-08
   次浏览      
 

设设计模式之外观模式(Facade)摘录

Facade:

(1)、意图: 为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

(2)、动机:将一个系统划分成为若干个子系统有利于降低系统的复杂性。一个常见的设计目标是使子系统间的通信和相互依赖关系达到最小。达到该目标的途径之一是就是引入一个外观(facade)对象,它为子系统中较一般的设施提供了一个单一而简单的界面。

(3)、适用性:在遇到以下情况适用Facade模式:

A、当你要为一个复杂子系统提供一个简单接口时。子系统往往因为不断演化而变得越来越复杂。大多数模式使用时都会产生更多更小的类。这使得子系统更具可重用性,也更容易对子系统进行定制,但这也给那些不需要定制子系统的用户带来一些使用上的困难。Facade可以提供一个简单的缺省视图,这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过facade层。

B、客户程序与抽象类的实现部分之间存在着很大的依赖性。引入Facade将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。

C、当你需要构建一个层次结构的子系统时,使用facade模式定义子系统中每层的入口点。如果子系统之间是相互依赖的,你可以让它们仅通过facade进行通讯,从而简化了它们之间的依赖关系。

(4)、优点:

A、它对客户屏蔽子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便。

B、它实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件往往是紧耦合的。松耦合关系使得子系统的组件变化不会影响到它的客户。Facade模式有助于建立层次结构系统,也有助于对对象之间的依赖关系分层。Facade模式可以消除复杂的循环依赖关系。这一点在客户程序与子系统是分别实现的时候尤为重要。在大型软件系统中降低编译依赖性至关重要。在子系统类改变时,希望尽量减少重编译工作以节省时间。用Facade可以降低编译依赖性,限制重要系统中较小的变化所需的重编译工作。Facade模式同样也有利于简化系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。

C、如果应用需要,它并不限制它们使用子系统类。因此你可以在系统易用性和通用性之间加以选择。

(5)、注意事项:

A、降低客户----子系统之间的耦合度:用抽象类实现Facade而它的具体子类对应于不同的子系统实现,这可以进一步降低客户与子系统的耦合度。这样,客户就可以通过抽象的Facade类接口与子系统通讯。这种抽象耦合关系使得客户不知道它使用的是子系统的哪一个实现。除生成子类的方法以外,另一种方法是用不同的子系统对象配置Facade对象。为定制facade,仅需对它的子系统对象(一个或多个)进行替换即可。

B、公共子系统类与私有子系统类:一个子系统与一个类的相似之处是,它们都有接口并且它们都封装了一些东西----类封装了状态和操作,而子系统封装了一些类。考虑一个类的公共和私有接口是有益的,我们也可以考虑子系统的公共和私有接口。子系统的公共接口包含所有的客户程序可以访问的类;私有接口仅用于对子系统进行扩充。当然,Facade类是公共接口的一部分,但它不是唯一的部分,子系统的其它部分通常也是公共的。私有化子系统类确实有用,但是很少有面向对象的编程语言支持这一点。

(6)、相关模式:AbstractFactory模式可以与Facade模式一起使用以提供一个接口,这一接口可用来以一种子系统独立的方式创建子系统对象。Abstract Factory也可以代替Facade模式隐藏那些与平台相关的类。Mediator模式与Facade模式的相似之处是,它抽象了一些已有的类的功能。然而,Mediator的目的是对同事之间的任意通讯进行抽象,通常集中不属于任何单个对象的功能。Mediator的同事对象知道中介者并与它通信,而不是直接与其他同类对象通信。相对而言,Facade模式仅对子系统对象的接口进行抽象,从而使它们更容易使用;它并不定义新功能,子系统也不知道Facade的存在。通常来讲,仅需要一个Facade对象,因此Facade对象通常属于Singleton模式。

为子系统的一组接口提供一个一致的界面。使用户使用起来更加方便。

Facade模式在高层提供了一个统一的接口,解耦了系统。设计模式中还有另一种模式Mediator也和Facade有类似的地方。但是Mediator主要目的是对象间的访问的解耦(通讯时候的协议)。

示例代码1:

#include <iostream>
#include <string>
using namespace std;
class SubSysOne
{
public:
void MethodOne()
{
cout<<"方法一"<<endl;
}
};
class SubSysTwo
{
public:
void MethodTwo()
{
cout<<"方法二"<<endl;
}
};
class SubSysThree
{
public:
void MethodThree()
{
cout<<"方法三"<<endl;
}
};
//外观类
class Facade
{
private:
SubSysOne* sub1;
SubSysTwo* sub2;
SubSysThree* sub3;
public:
Facade()
{
sub1 = new SubSysOne();
sub2 = new SubSysTwo();
sub3 = new SubSysThree();
}
~Facade()
{
delete sub1;
delete sub2;
delete sub3;
}
void FacadeMethod()
{
sub1->MethodOne();
sub2->MethodTwo();
sub3->MethodThree();
}
};
//客户端
int main()
{
Facade* test = new Facade();
test->FacadeMethod();
/*result
方法一
方法二
方法三
*/
return 0;
}

示例代码2:

Facade.h:

#ifndef _FACADE_H_
#define _FACADE_H_
class Subsystem1
{
public:
Subsystem1();
~Subsystem1();
void Operation();
protected:
private:
};
class Subsystem2
{
public:
Subsystem2();
~Subsystem2();
void Operation();
protected:
private:
};
class Facade
{
public:
Facade();
~Facade();
void OperationWrapper();
protected:
private:
Subsystem1* _subs1;
Subsystem2* _subs2;
};
#endif //~_FACADE_H_

Facade.cpp:

#include "Facade.h"
#include <iostream>
using namespace std;
Subsystem1::Subsystem1()
{
}
Subsystem1::~Subsystem1()
{
}
void Subsystem1::Operation()
{
cout<<"Subsystem1 operation ..."<<endl;
}
Subsystem2::Subsystem2()
{
}
Subsystem2::~Subsystem2()
{
}
void Subsystem2::Operation()
{
cout<<"Subsystem2 operation ..."<<endl;
}
Facade::Facade()
{
this->_subs1 = new Subsystem1();
this->_subs2 = new Subsystem2();
}
Facade::~Facade()
{
delete _subs1;
delete _subs2;
}
void Facade::OperationWrapper()
{
this->_subs1->Operation();
this->_subs2->Operation();
}

main.cpp:

#include "Facade.h"
#include <iostream>
using namespace std;
int main()
{
Facade* f = new Facade();
f->OperationWrapper();
/*result
Subsystem1 operation ...
Subsystem2 operation ...
*/
return 0;
}

外观模式结构图:

设计模式之代理模式(Proxy)摘录

Proxy:

(1)、意图: 为其它对象提供一种代理以控制对这个对象的访问。

(2)、适用性:在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用Proxy模式。

A、远程代理(Remote Proxy):为一个对象在不同的地址空间提供局部代表。

B、虚代理(Virtual Proxy):根据需要创建开销很大的对象。

C、保护代理(Protection Proxy):控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。

D、智能指针(Smart Reference):取代了简单的指针,它在访问对象时执行一些附加操作。它的典型用途包括:a、对指向实际对象的引用计数,这样当该对象没有引用时,可以自动释放它。b、当第一次引用一个持久对象时,将它装入内存。c、在访问一个实际对象前,检查是否已经锁定了它,以确保其它对象不能改变它。

(3)、相关模式:

A、适配器Adapter为它所适配的对象提供了一个不同的接口。相反,代理提供了与它的实体相同的接口。然而,用于访问保护的代理可能会拒绝执行实体会执行的操作,因此,它的接口实际上可能只是实体接口的一个子集。

B、尽管Decorator的实现部分与代理相似,但decorator的目的不一样。Decorator为对象添加一个或多个功能,而代理则控制对对象的访问。代理的实现与Decorator的实现类似,但是在相似的程度上有所差别。Protection Proxy的实现可能与Decorator的实现差不多。另一方面,Remote Proxy不包含对实体的直接引用,而只是一个间接引用。Virtual Proxy开始的时候使用一个间接引用,例如一个文件名,但最终将获取并使用一个直接引用。

远程代理:可以隐藏一个对象在不同地址空间的事实。

虚拟代理:通过代理来存放需要很长时间实例化的对象。

安全代理:用来控制真实对象的访问权限。

智能引用:当调用真实对象时,代理处理另外一些事。

Proxy模式的最大的好处就是实现了逻辑和实现的彻底解耦。

示例代码1:

#include <string>
#include <iostream>
using namespace std;
//定义接口
class Interface
{
public:
virtual void Request() = 0;
};
//真实类
class RealClass : public Interface
{
public:
virtual void Request()
{
cout<<"真实的请求"<<endl;
}
};
//代理类
class ProxyClass : public Interface
{
private:
RealClass* m_realClass;
public:
virtual void Request()
{
m_realClass = new RealClass();
m_realClass->Request();
delete m_realClass;
}
};
//客户端
int main()
{
ProxyClass* test = new ProxyClass();
test->Request();
/*result
真实的请求
*/
return 0;
}

示例代码2:

Proxy.h:

#ifndef _PROXY_H_
#define _PROXY_H_
class Subject
{
public:
virtual ~Subject();
virtual void Request() = 0;
protected:
Subject();
private:
};
class ConcreteSubject : public Subject
{
public:
ConcreteSubject();
~ConcreteSubject();
void Request();
protected:
private:
};
class Proxy
{
public:
Proxy();
Proxy(Subject* sub);
~Proxy();
void Request();
protected:
private:
Subject* _sub;
};
#endif//~_PROXY_H_

Proxy.cpp:

#include "Proxy.h"
#include <iostream>
using namespace std;
Subject::Subject()
{
}
Subject::~Subject()
{
}
ConcreteSubject::ConcreteSubject()
{
}
ConcreteSubject::~ConcreteSubject()
{
}
void ConcreteSubject::Request()
{
cout<<"ConcreteSubject ... request ..."<<endl;
}
Proxy::Proxy()
{
}
Proxy::Proxy(Subject* sub)
{
_sub = sub;
}
Proxy::~Proxy()
{
delete _sub;
}
void Proxy::Request()
{
cout<<"Proxy request ..."<<endl;
_sub->Request();
}

main.cpp:

#include "Proxy.h"
#include <iostream>
using namespace std;
int main()
{
Subject* sub = new ConcreteSubject();
Proxy* p = new Proxy(sub);
p->Request();
/*result
Proxy request ...
ConcreteSubject ... request ...
*/
return 0;
}

代理模式结构图:

   
次浏览       
相关文章

为什么要做持续部署?
剖析“持续交付”:五个核心实践
集成与构建指南
持续集成工具的选择-装载
 
相关文档

持续集成介绍
使用Hudson持续集成
持续集成之-依赖管理
IPD集成产品开发管理
相关课程

配置管理、日构建与持续集成
软件架构设计方法、案例与实践
单元测试、重构及持续集成
基于Android的单元、性能测试
最新活动计划
LLM大模型应用与项目构建 12-26[特惠]
QT应用开发 11-21[线上]
C++高级编程 11-27[北京]
业务建模&领域驱动设计 11-15[北京]
用户研究与用户建模 11-21[北京]
SysML和EA进行系统设计建模 11-28[北京]

重构-使代码更简洁优美
Visitor Parttern
由表及里看模式
设计模式随笔系列
深入浅出设计模式-介绍
.NET中的设计模式
更多...   

相关培训课程

J2EE设计模式和性能调优
应用模式设计Java企业级应用
设计模式原理与应用
J2EE设计模式指南
单元测试+重构+设计模式
设计模式及其CSharp实现


某电力公司 设计模式原理
蓝拓扑 设计模式原理及应用
卫星导航 UML & OOAD
汤森路透研发中心 UML& OOAD
中达电通 设计模式原理
西门子 嵌入式设计模式
更多...