关闭

设计模式学习笔记——结构模式

391人阅读 评论(0) 收藏 举报

1.门面模式 Facade
 作用:为子系统中的一组接口提供一个一致的界面;
 详解:客户需要服务时,不需要分开跑每个部门,只需要在便民服务台一坐,剩下的事情就交由服务人员代劳了(子系统功能繁杂,采用统一的门面接口整合其功能,向客户程序提供相应的服务); <典型应用:数据库JDBC优化>
 优点:对客户屏蔽子系统组件,减少客户处理对象的数目,从而使子系统使用起来更加方便;
    降低客户程序与子系统之间的耦合度,调整子系统功能和结构对客户程序影响不大,同时降低了编译依赖性;
    对两层之间的调用粗颗粒化很有帮助,避免了大量细颗粒度的访问。

2.代理模式 Proxy
 作用:为其他对象提供一种代理以控制对这个对象的访问;
 详解:用代理模式进行权限控制的情形,工厂生产出来了的产品,交由代理商卖,代理商根据客户的实际情况(比如钱够不够)来决定用户能否拥有这个产品(真实产品类和代理商产品类都实现一个共同的抽象产品接口,抽象接口和真实产品类包含的方法一般一致,仅包含产品本身应该具有的一些特性或功能,代理商产品类一般包含私有的抽象产品接口和存储客户权限的变量,权限变量在代理商产品类的带参构造函数中初始化,在实现抽象产品类方法中,先判断权限然后才决定是否将真实产品类实例交由客户调用;客户需要将自己的权限作为参数传给代理商产品类的带参构造函数,而后间接的使用真实产品类);
 优点:在一定程序上降低了系统的耦合度,更好的使用对象等。

3.适配器模式 Adapter
 作用:将一个类的接口转化为客户希望的另外一个接口,使接口不兼容而不能在一起工作的类可以一起工作;
 详解:适配器模式分为类适配器模式(继承)和对象适配器模式(组合),区别仅在于适配器角色对被适配角色的适配是通过继承完成的还是通过组合完成的;
    对象适配器模式中适配器类继承了想要扩展功能的基类,包含私有的被适配类对象,并且在适配器类的构造函数中初始化这个被适配对象,并且在客户规定的方法中调用了被适配对象原有的方法;
 辨别:一般而言,代理模式不改变向外提供的方法的命名,而只是对已有接口功能的一种控制;适配器模式则强调转换成客户规定的方法命名;
    java中有一种“缺省适配模式”,它是为一个接口提供缺省的实现,这样子类型就可以从缺省适配模式中进行扩展,避免从原有接口中扩展时要实现一些自己不关心的接口,这个和我们这里说的“适配器模式”完全不同。

4.组合模式 Composite
 作用:将对象以树形结构组织起来,以达成“部分-整体”层次结构,使得客户端对单个对象和组合对象的使用具有一致性;
 详解:组合模式有偏向安全性和偏向透明性两种实现方式;
    偏向安全性的组合模式中,我们抽象一个组件类或接口,其中仅包含叶子结点和树枝对象共同的基本方法,单个对象类和组合对象类都需要继承或实现这个类或接口,差别在于单个对象类仅需要实现这个共同的基本方法,而组合对象类除了实现共同方法,还要提供增加、删除组件及获取子节点方法(JUnit实现);
    在偏重透明性的组合模式中,我们抽象一个组件类或接口,其中包含叶子结点和树枝对象共同的基本方法,和增加、删除组件及获取子节点方法,无论单个对象类还是组合对象类都需要继承或实现这个类或接口,差别仅在实现共同方法时单个对象不需要考虑递归遍历子节点而组合对象需要考虑,这样我们通过抽象接口就可以向外提供无差别的共同方法(盘盒、箱子例子);
 优点:客户端可以一致的使用组合结构或其中的单个对象,简化了客户端代码;
    更容易在组合体内加入对象部件,客户端不必因为加入了新的对象部件而更改代码(符合开闭原则);
 缺点:组合模式不容易限制组合中的构件。

5.装饰模式 Decorator
 作用:动态的给一个对象添加一些额外的职责,就增加功能来说,Decorator模式比生成子类方式更加灵活;
 详解:普通的门具有普通门的一般行为(如开、关),现在我们想要给这个门添加一个报警的功能,于是我们有两种选择,专门制造一种可以报警的门;或者制造一种报警系统,将门放到这个系统里就可以了<当然,你也可以考虑会报警的窗户呵呵>(先定义个入口的抽象类或接口,实际的门和报警系统都继承或实现这个抽象入口类或接口,然后在报警系统类里定义实际门这个类和一些新的方法,这些方法需要调用实际门类的方法;客户今天使用的就是报警系统这个类,调用的是报警系统的方法);
 辨别:个人感觉装饰模式和代理模式很像,但是还是有一些差别的,代理模式主要还是用的被代理对象原有的功能,而装饰模式更侧重于在被装饰对象上加上一些新的功能。

6.桥梁模式 Bridge
 作用:将抽象部分与它的实现部分分离,使它们都可以独立的变化;
 详解:咖啡有大杯、中杯、小杯,每种又都可以加糖、加奶或不加,这样如果分别实现有3*3种不同的咖啡(太多了...),于是我们将咖啡按大小分类,抽象出共同的行为如选择加糖等(定义一个抽象咖啡类,包含共同的行为接口和一些抽象方法<如冲咖啡方法>,具体咖啡类<如大杯咖啡类>继承咖啡类,将行为接口通过构造函数等方式赋值给这个具体咖啡类,之后就可以在这个具体咖啡类的抽象方法中调用接口实现方法;另一方面,行为接口里只需要定义行为,而具体的实现交给实现类去做,显然,这样我们就将咖啡的抽象和具体实现分离了,因为抽象类里只包含了抽象的方法和接口,这就是一个桥);
 场合:<Business Object、DAO、数据库操作等>
    当系统中有多个地方要使用到类似的行为或类似行为的组合时,为了提高重用和减少因行为差异而产生的子类;
    当系统中某个类的行为可能有几种不同的变化趋势,为了有效的将变化封装;
    当行为可能要被不同相似类使用;
 好处:<使用低耦合性的组合代替继承>
    将可能变化的部分单独封装起来,使变化产生的影响最小,不用编译不必要的代码;
    抽象部分和实现部分可以单独的变动,并且每一部分的扩充都不会破坏桥梁模式搭起来的架子;
    对客户程序来说,实现细节是透明的。

7.享元模式 Flyweight
 作用:避免大量拥有相同内容的小类的开销(如耗费内存),使大家共享一个类(元类);
 详解:享元模式分为单纯享元模式和复合享元模式,其中复合享元模式中复合享元角色包含一系列单纯享元角色,用组合模式使其对外一致,也正由于其复合的特点,没有达到享元模式所要求的共享特性;
    享元模式的关键在于享元工厂角色,它负责创建和维护享元角色,达到共享的目的,享元工厂一般管理一个享元角色容器,通过享元工厂我们可以创建、控制调用、修改享元角色,达到一个对象重复使用的目的;
    当然,也有用静态属性的方法来实现复合享元模式的,不予评论。
 优劣:享元模式能大幅降低内存中对象的数量,但也使系统逻辑复杂化,可以说享元模式是用时间换取空间的。
 辨别:享元模式和单例模式在实现手法上有类似的地方,但是侧重完全不同,享元是为了提高对象重用性出发的,而单例是为了限制对象的创建出发的,当然还有别的区别,用到不多,不讨论。
 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:401907次
    • 积分:4196
    • 等级:
    • 排名:第7759名
    • 原创:35篇
    • 转载:242篇
    • 译文:2篇
    • 评论:70条
    最新评论