设计模式——结构型模式

来源:互联网 发布:excle怎么做数据分析 编辑:程序博客网 时间:2024/04/30 09:34


结构型模式描述如何组织类和对象以组成更大的结构。结构型类模式采用继承机制来组合接口和实现,结构型对象模式则采用组合聚合来组合对象以实现新功能,可以在运行时刻改变对象组合关系,具有更大灵活性,故这里只关注结构型对象模式。


结构型模式包括7种:ABCDFFP适配器模式(Adapter)、装饰模式(Decorator)、桥接模式(Bridge)、组合模式(Composite)、享元模式(Flyweight)、代理模式(Proxy)和外观模式(Facade)。

1.适配器模式(Adapter)使由于接口不兼容而不能一起工作的类可以一起工作。有类或对象适配器模式,解决已存在目标客户接口和已存在功能类接口不兼容的问题。对象适配器模式实现上是适配器对象包含一个被适配器对象来进行接口转换;一般是项目改造或扩充时才用到。适配器模式使得一个接口和其它接口兼容,从而给出了多个不同接口的统一抽象。

 

协作:Client在Adapter的实例上调用一些操作,适配器调用含有的Adaptee对象实现这个操作。

2.桥接模式(Bridge):将抽象和实现分离,使他们可以独立的变化。分离接口和实现,从而使抽象类的实现可以在运行时刻配置,在运行时刻改变其对象的实现;接口实现分离有利于系统分层,从而产生跟好的结构化系统,可以独立的对Abstractation和Implementor层次结构进行扩充。封装多维变化,抽象角色内含一个抽象实现角色,精确抽象角色调用父类中的抽象实现角色对象实现,具体实现角色继承抽象实现角色,如果再增加一维抽象,可以当抽象实现角色,在原有的抽象实现角色中包含新增的抽象实现角色,也可以当成新的抽象角色,原有的抽象角色作为一个抽象实现角色;这样说该模式实现时从抽象实现角色这维变化最好。实例:不同人开不同车在不同路上行驶;不同名牌手机有不同系统不同软件功能;

协作:Abstraction将Client的请求转发给它的Implementor对象。

3.组合模式:将对象组合成树状层次结构,使用户对单个对象和组合对象具有一致的访问性。即组合模式定义树状结构,可以将子对象当成整体对象一样处理;抽象构件对象,树枝构件对象,树叶构件对象,根据叶子是否当成枝干来看待可分为透明性和安全性两种模式。组合模式必须提供管理子对象的方法,但管理对象的方法是在Component中就声明还是在Composite中声明呢?如下图在Component中声明所有用来管理子类对象的方法,以达到Component接口的最大化,从而使客户在接口层次上看树叶和树枝没有区别——透明性,但树叶是不存在子类的,可能有安全问题。

下图只在Composite中声明所有管理子类的方法,避免了上面的安全性问题,但是树枝和叶子又不同的接口,失去了透明性。

协作:用户使用Component类接口与组合结构中的对象交互,如果接收者是一个叶节点,则直接处理请求,如果接受者是Composite,它通常将请求发送给它的子部件,再转发请求之前或之后可能执行一些辅助操作。

实例:java单元测试框架Junit定义了两个概念:TestCase和TestSuite,前者是一个编写测试的类,后者是一个不同TestCase的集合,集合里也可以再包含TestCase,这样运行一个TestSuite会将其包含的TestCase全部运行。Junit采用了组合模式将TestCase和TestSuite统一起来,创建一个Test接口来扮演Component角色,TestCase扮演Leaf角色,Testsuite扮演Composite角色。Junit是一个偏重安全性的组合模式,因此用TestCase和Testsuite时不能直接用Test代替。

4.装饰者模式(Decorator):动态的给对象增加一些职责,比生成子类更灵活。装饰者模式描述了如何动态的给对象增加职责,采用递归方式组合对象从而允许你添加任意多的职责。

参与者:a抽象构件角色(Component):定义抽象接口,以规范准备接收附加职责的对象。

        b具体构件角色(ConcreteComponent):被装饰者。

        c装饰角色(Decorator):持有一个构件对象实例,并定义了抽象构件定义的接口。

        d具体装饰角色(ConcreteDecorator):负责给构件增加功能。

协作:Decorator将请求转发给它的Component对象,并有可能在转发请求前后执行一些附加的动作。

实例:Junit采用了装饰模式,在java.extensions包中,TestDecorator、RepeatedTest便是对TestCase的装饰模式的扩展。使用方法如:TestDecorator test=new RepeatedTest(new TestXX(),3);。

5.外观模式(Facade):为子系统中的一组接口提供一个一致的界面,使这一子系统更加容易使用。外观模式用于给多个子系统定义一套统一的外观,描述了如何用单个对象表示整个子系统。Façade被客户角色调用,熟悉子系统的功能,内部根据客户角色已有的需求预定了几种功能组合。

协作:客户程序通过发送请求给Façade的方式与子系统通信,Façade将这些消息转发给适当的子系统对象;使用Façade的客户程序不需要直接访问子系统对象。

6.亨元模式:运用共享技术有效的支持大量细粒度对象。java中string的实现,细化对象共享粒度;

参与者:a.Flyweight:描述一个接口可以接受并作用于外部状态。

b.ConcreteFlyweight:实现Flyweight并为内部状态增加存储空间。ConcreteFlyweight对象必须是可共享的,它所存储的状态必须是内部的。

c.unsharedConcreteFlyweight:并非所有Flyweight子类都需要被共享,unsharedConcreteFlyweight对象通常将ConcreteFlyweight对象作为子节点。

d.FlyweightFactory:创建并管理flyweight对象,确保合理的共享flyweight。当用户请求一个flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(不存在的话)。

e.维持一个对flyweight的引用,计算或存储flyweight的外部状态。

协作:flyweight执行所需的状态必定是内部的或外部的,内部的状态存储与ConcreteFlyweight对象之中,而外部对象由Client对象存储或计算。当用户调用flyweight操作时将该状态传递给它。用户不应直接对ConcreteFlyweight类进行实例化,而只能从FlyweightFactory对象得到ConcreteFlyweight对象,这样可以保证它们适当地进行共享。

7.代理模式(Proxy):为其它对象提供一种代理以控制对这种对象的访问。代理模式提供了对对象的一些特有性质的一定程度上的间接访问,从而限制、增强或修改这些性质。

协作:代理根据其种类,在适当的时候向RealSubsject转发请求。

常见使用代理模式的情况:a远程代理:为一个对象在不同的地址空间提供局部代表。

b.虚代理:根据需要创建开销很大的对象。

c.保护代理:控制对原始对象的访问权限。

d.取代了简单的指针,它在访问对象时执行一些附加操作。




0 0