设计模式 ② — 结构型模式
代理模式(PROXY)
代理模式也叫委托模式,日常生活中我们接触的最常见的就是代理上网。
为其他对像提供一种代理以控制对这个对象的访问。
当无法或者不想直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端透明性,委托对象与代理对象需要实现相同的接口。
Subject : 抽象主题类。
RealSubject : 真实主题类。
ProxySubject : 代理类。
Client : 客户类。
Android源码里的ActivitManagerProxy代理类。
组合模式也称为部分整体模式,结构型设计模式之一。
将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的实用具有一致性。
当发现需求中是体现部分与整体层次结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑组合模式了。
Component :抽象根节点,为组合中的对象声明接口。
Leaf :组合中表示叶子节点对象。
输出结果:
Android源码里的实现:
View和ViewGroup的嵌套组合。
组合模式可以清楚的定义分层次的复杂对象,方便对整个层次结构进行控制。
新增构件时不好对枝干的构建类型进行限制,因为他们来自于相同的抽象层,因此,必须要时刻进行类型检查来实现,这个过程较为复杂。
适配器是将两个不兼容的类融合在一起工作。
适配器模式把一个类的接口编程客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
1.系统需要使用现有的类,此类的接口不符合系统的需要,即接口不兼容。2.需要一个统一的输出接口, 而输入端的内容不可预知。
3.建立一个可以重复引用的类,用于与一些没有太大关联的类,一些将来可能引进的类一起工作。
类的适配器:
对象的适配器:
两者的区别:
类适配器是客户类有一个接口规范的情况下可用,此时适配类只需作为功能类的子类,并实现接口并可,直接用功能类实现了客户类的要求。
对象适配类是在客户类没有提供接口的情况下用的,适配类作为客户类的子类,并在其中实例化一个功能类的对象,并调用此对象的方法实现适配,故称对象适配。
ListView里的Adapter,将数据和视图适配到一起。
1.更好的复用性,更好的扩展性
1.过多使用了适配器,会让系统很乱,不易整体把控。
享元模式(FLYWEIGHT)
对象池的一种实现,用来尽可能减少内存使用量,适用于存在大量重复对象的场景。
使用共享对象可有效支持大量细粒度的对象。
1.系统中存在大量的相似对象。
2.细粒度的对象都具备比较接近的外部状态,内部状态与环境无关,对象没有特定身份。
3.需要缓冲池的场景。
对象池的一种实现,用来尽可能减少内存使用量,适用于存在大量重复对象的场景。
使用共享对象可有效支持大量细粒度的对象。
1.系统中存在大量的相似对象。
2.细粒度的对象都具备比较接近的外部状态,内部状态与环境无关,对象没有特定身份。
3.需要缓冲池的场景。
Flyweight : 享元对象抽象基类或者接口。
ConcreteFlyweight : 具体的享元对象。
FlyweightFactory : 享元工厂,负责管理享元对象池和创建享元对象。
Android中SQLiteCompiledSql的使用,是很多数据库系统典型的实现。
SQLiteCompiledSql就是这样的一个需要共享的享元对象
1. 减少系统中对象的个数。
2. 使用了外部状态,外部状态相对独立,不会影响内部状态,享元模式使得享元对象能够在不同环境中被共享。
1. 由于享元模式需要区分内外状态,所以程序更加复杂化了。
2. 为了使对象可共享,享元模式需要将享元对象状态外部化,读取外部状态使运行时间变长。
外观模式是统一封装接口,将子系统的逻辑、交互隐藏起来,位用户提供一个高层次的接口,使系统更加易用,同时隐藏具体实现
要求子系统的外部和内部的通信必须通过一个统一的对象进行,门面模式提供一个高层次接口,使子系统更易于使用。
1.为复杂的子系统提供简单的接口。
2.当你需要构建一个层次结构的子系统时,使用facade模式定义子系统中每层的入口点。
Facade:将所有从客户端发来的请求委派到相应的子系统去,传递给相应的子系统对象处理。
SubSystem:每一个子系统都可以被客户端直接调用,或者被外观角色调用,它处理由外观类传过来的请求;子系统并不知道外观的存在,对于子系统而言,外观角色仅仅是另外一个客户端而已。
Android开发中的Context就是一个外观模式,Context是一个很多接口的抽象类。
1. 隐藏子系统细节,减少耦合,能够拥抱变化。
2. 外观类对子系统接口封装,使系统更加易用。
1. 外观类接口膨胀,一定程序上增加了用户的实用成本。
2. 外观类没有遵循开闭原则,业务变更时,可能需要直接修改外观类。
桥接模式也叫桥梁模式,是结构型设计模式之一。承担着连接2边的作用。
将抽象部分与现实部分分离,使他们可以独立的进行变化。
这里桥梁的作用就是连接“抽象部分”与“实现部分”,事实上,任何多维度的变化或者说多个树状类之间的耦合都可以用桥接模式来解耦。
Abstraction : 抽象部分
Implementor : 实现部分
ConcreteImplementorA B : 实现部分的具体实现
View的视图层级中,将button,textview等绘制到屏幕上的displayList和canvas,他们之间的关系就是一种桥接模式。
分离抽象和实现,灵活的扩展和对客户来说透明的实现
不容易设计。
也称为包装模式,是继承关系的替代方案之一。
动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
需要透明且动态的扩展类的功能时。
Component : 抽象组件。
ConcreteComponent : 组件具体实现类。
Decorator : 抽象装饰者。
ConcreteDecoratorA : 装饰者具体实现类。
在Android源码中,其中使用到装饰模式的就是由Context ,ContextWrapper等设计。