什么是设计模式
设计模式是一系列在实践中总结出来的可复用的面向对象的软件设计方法。
设计模式是一套被反复使用、多数人知晓的、经过分类编目的、**设计经验的总结。使用设计模式是为了可重用**、让**更容易被他人理解、保证**可靠性。
一》creational patterns 创建型模式。
工厂模式。定义:提供创建对象的接口。
为什么工厂模式是如此常用?因为工厂模式就相当于创建实例对象的new,我们经常要根据类class生成实例对象,如a a=new a() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑实用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。
factory 抽象工厂模式。
工厂模式中有: 工厂方法(factory method) 抽象工厂(abstract factory).
这两个模式区别在于需要创建对象的复杂程度上。
method 工厂方法模式
在实际应用中,工厂方法用得比较多一些,而且是和动态类装入器组合在一起应用,工厂方法确实为系统结构提供了非常灵活强大的动态扩展机制,只要我们更换一下具体的工厂方法,系统其他地方无需一点变换,就有可能将系统功能进行改头换面的变化。
建造者模式
builder模式定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
builder模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象的类型和内容就可以构建它们。用户不知道内部的具体构建细节。builder模式是非常类似抽象工厂模式,细微的区别大概只有在反复使用中才能体会到。
为何使用?是为了将构建复杂对象的过程和它的部件解耦。注意: 是解耦过程和部件。
因为一个复杂的对象,不但有很多大量组成部分,如汽车,有很多部件:车轮方向盘发动机还有各种小零件等等,部件很多,但远不止这些,如何将这些部件装配成一辆汽车,这个装配过程也很复杂(需要很好的组装技术),builder模式就是为了将部件和组装过程分开。
原型模式。原型模式定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。
如何使用?因为j**a中的提供clone()方法来实现对象的克隆,所以prototype模式实现一下子变得很简单。
单例模式。单态定义:singleton模式主要作用是保证在j**a应用程序中,一个类class只有一个实例存在。
在很多操作中,比如建立目录数据库连接都需要这样的单线程操作。还有, singleton能够被状态化; 这样,多个单态类在一起就可以作为一个状态仓库一样向外提供服务,比如,你要论坛中的帖子计数器,每次浏览一次需要计数,单态类能否保持住这个计数,并且能synchronize的安全自动加1,如果你要把这个数字永久保存到数据库,你可以在不修改单态接口的情况下方便的做到。另外方面,singleton也能够被无状态化。
提供工具性质的功能,singleton模式就为我们提供了这样实现的可能。使用singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于j**a垃圾**(garbage collection)。
我们常常看到工厂模式中类装入器(class loader)中也用singleton模式实现的,因为被装入的类实际也属于资源。
二》structural patterns 结构型模式。
适配器模式。
适配器模式定义:将两个不兼容的类纠合在一起使用,属于结构型模式,需要有adaptee(被适配者)和adaptor(适配器)两个身份。
为何使用?我们经常碰到要将两个没有关系的类组合在一起使用,第一解决方案是:修改各自类的接口,但是如果我们没有源**,或者,我们不愿意为了一个应用而修改各自的接口。
怎么办? 使用adapter,在这两种接口之间创建一个混合接口(混血儿).
桥接器/桥梁模式。
bridge模式定义 :将抽象和行为划分开来,各自独立,但能动态的结合。
任何事物对象都有抽象和行为之分,例如人,人是一种抽象,人分男人和女人等;人有行为,行为也有各种具体表现,所以,“人”与“人的行为”两个概念也反映了抽象和行为之分。
在面向对象设计的基本概念中,对象这个概念实际是由属性和行为两个部分组成的,属性我们可以认为是一种静止的,是一种抽象,一般情况下,行为是包含在一个对象中,但是,在有的情况下,我们需要将这些行为也进行归类,形成一个总的行为接口,这就是桥模式的用处。
为什么使用?不希望抽象部分和行为有一种固定的绑定关系,而是应该可以动态联系的。
如果一个抽象类或接口有多个具体实现(子类、concrete subclass),这些子类之间关系可能有以下两种情况:
1. 这多个子类之间概念是并列的,如前面举例,打桩,有两个concrete class:方形桩和圆形桩;这两个形状上的桩是并列的,没有概念上的重复。
2.这多个子类之中有内容概念上重叠。那么需要我们把抽象共同部分和行为共同部分各自独立开来,原来是准备放在一个接口里,现在需要设计两个接口:
抽象接口和行为接口,分别放置抽象和行为。
例如,一杯咖啡为例,子类实现类为四个:中杯加奶、大杯加奶、 中杯不加奶、大杯不加奶。
但是,我们注意到:上面四个子类中有概念重叠,可从另外一个角度进行考虑,这四个类实际是两个角色的组合:抽象和行为,其中抽象为:
中杯和大杯;行为为:加奶不加奶(如加橙汁加苹果汁).
实现四个子类在抽象和行为之间发生了固定的绑定关系,如果以后动态增加加葡萄汁的行为,就必须再增加两个类:中杯加葡萄汁和大杯加葡萄汁。显然混乱,扩展性极差。
那我们从分离抽象和行为的角度,使用bridge模式来实现。
如何实现?以上面提到的咖啡为例。 我们原来打算只设计一个接口(抽象类),使用bridge模式后,我们需要将抽象和行为分开,加奶和不加奶属于行为,我们将它们抽象成一个专门的行为接口。
posite 合成模式/组合模式。
composite模式定义:将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。
composite比较容易理解,想到composite就应该想到树形结构图。组合体内这些对象都有共同接口,当组合体一个对象的方法被调用执行时,composite将遍历(iterator)整个树形结构,寻找同样包含这个方法的对象并实现调用执行。可以用牵一动百来形容。
所以composite模式使用到iterator模式,和chain of responsibility模式类似。
composite好处:
1.使客户端调用简单,客户端可以一致的使用组合结构或其中单个对象,用户就不必关系自己处理的是单个对象还是整个组合结构,这就简化了客户端**。
2.更容易在组合体内加入对象部件。 客户端不必因为加入了新的对象部件而更改**。
如何使用composite?首先定义一个接口或抽象类,这是设计模式通用方式了,其他设计模式对接口内部定义限制不多,composite却有个规定,那就是要在接口内部定义一个用于访问和管理composite组合体的对象们(或称部件component).
装饰/油漆工模式。
decorator定义:动态给一个对象添加一些额外的职责,就象在墙上刷油漆。使用decorator模式相比用生成子类方式达到功能的扩充显得更为灵活。
装饰模式:decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象我们称decoratee.这两种实体在decorator模式中是必须的。
为什么使用decorator?我们通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生成很多子类,增加系统的复杂性,同时,使用继承实现功能拓展,我们必须可预见这些拓展功能,这些功能是编译时就确定了,是静态的。
使用decorator的理由是:这些功能需要由用户动态决定加入的方式和时机。decorator提供了"即插即用"的方法,在运行期间决定何时增加何种功能。
如何使用?举adapter中的打桩示例,在adapter中有两种类:方形桩圆形桩,adapter模式展示如何综合使用这两个类,在decorator模式中,我们是要在打桩时增加一些额外功能,比如,挖坑在桩上钉木板等,不关心如何使用两个不相关的类。
门面/外观模式模式。
facade模式的定义: 为子系统中的一组接口提供一个一致的界面。
在应用中,经常需要对数据库操作,每次都写上述一段**肯定比较麻烦,需要将其中不变的部分提炼出来,做成一个接口,这就引入了facade外观对象。
享元模式(共享元类)
为什么使用?面向对象语言的原则就是一切都是对象,但是如果真正使用起来,有时对象数可能显得很庞大,比如,字处理软件,如果以每个文字都作为一个对象,几千个字,对象数就是几千,无疑耗费内存,那么我们还是要"求同存异",找出这些对象群的共同点,设计一个元类,封装可以被共享的类,另外,还有一些特性是取决于应用(context),是不可共享的,这也flyweight中两个重要概念内部状态intrinsic和外部状态extrinsic之分。
说白点,就是先捏一个的原始模型,然后随着不同场合和环境,再产生各具特征的具体模型,很显然,在这里需要产生不同的新对象,所以flyweight模式中常出现factory模式。flyweight的内部状态是用来共享的,flyweight factory负责维护一个flyweight pool(模式池)来存放内部状态的对象。
flyweight模式是一个提高程序效率和性能的模式,会大大加快程序的运行速度。应用场合很多:比如你要从一个数据库中读取一系列字符串,这些字符串中有许多是重复的,那么我们可以将这些字符串储存在flyweight池(pool)中。
设计模式慨念
什么是设计模式 设计模式是一系列在实践中总结出来的可复用的面向对象的软件设计方法。设计模式是一套被反复使用 多数人知晓的 经过分类编目的 设计经验的总结。使用设计模式是为了可重用 让 更容易被他人理解 保证 可靠性。一 creational patterns 创建型模式。工厂模式。定义 提供创建对象...
设计模式入门学习工厂模式
先读一本设计模式入门书,深入浅出设计模式,之后再拜读一下gof设计模式。工作也有两年时间了,说设计模式接触的应该比较多了,只是一直没有进行系统的整理。说起来,刚入职做webkit这让我有一个比较高的技术起点,技术视界也比较宽广。抓时间系统过一遍设计模式,下编码的艺术。工厂模式 为创建对象提供过渡接口...
设计模式学习笔记 命令模式
命令模式将请求封装成对象,以便使用不同的请求 队列或日志来参数化其他对象。命令模式也支持科撤销的操作。提供了用统一方法执行不同行为的简单机制。允许在运行时改变所处理的请求,以及如何处理请求。仅仅需要很少的 实现。当条件调度程序已经足够的时候,会增加设计的复杂度。命令模式将发出请求的对象和执行请求的对...