设计模式及分类
设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。设计模式分为以下3中:
1.系统架构模式
一般不着重于不同业务系统中共性问题的解决方案,是有关大尺度和粗粒度设计方案的重用,比如MVC等。
2.通用职责分配软件模式(GRASP模式--------General Responsibility Assignment Software Patterns)
帮助软件系统的开发者把握基本的对象设计技术,并且用一种系统的、可推理的、可说明的方式来应用面向对象技术中的各种设计理论和思想、原则,并指导软件系统的设计人员进行累职责的分配和类之间关系的确定;同时也是学习GOF设计模式的基础。
3.代码设计模式(如GOF的23中代码设计模式)
主要着重于通用原理和相同场景时的编程实现。GRASP指导如何进行累职责的分配、适用于累的分析和设计阶段,而GOF指导如何进行代码优化,适用于累的编码实现阶段。
架构和模式的最主要不同
架构
是一组有关如何确定软件系统的组织结构的重要决策,以及接口和它们相互协作的行为的选择,更加关注的是"高层设计"。
模式
关注的重点在于通过经验提取的"准则或指导方案"在设计中的应用。
架构设计中的模式
层模式
层体系架构模式(Layers Architecture Pattern)就是把应用系统中的各个部分分解成各个不同的子任务组或子系统。利用层架构模式来组织系统能够构造出一个层次化的系统结构。在系统的架构设计上,通常可以利用门面(外观)、控制器、中介等架构模式来实现系统设计中层与层之间的相互关联和协作。
MVC模式
模型---试图----控制器,能够有效地分离逻辑开发,使开发人员能专注于各自的开发实现工作。讲表示层和业务模型层之间分离和解耦,从而使表示层与业务处理层能够各自变化,而不会相互影响。
前端控制器模式
前段控制器模式可以实现对所有的请求进行同意处理并封装各种公共请求的处理,在这个模式中,所有的请求都被发送到一个前端控制器对象中,这个对象处理所有的请求,并且决定和选择其后的业务及控制器组件。
业务调度控制器模式
业务调度控制器Servlet一方面完成对前段表示层各个页面发送的请求数据的预处理;另一方面实现对后端的模型层组件的调度以完成具体业务功能的实现。
GRASP软件模式
1.信息专家模式
2.创建者模式
帮助软件系统的设计人员确定创建对象的职责具体由哪个类来承担,也就是某个类的对象实例应该由哪些相关的类来创建或者同意由某个类集中创建。
3.高内聚模式
4.低耦合模式
5.控制器模式
1.多态模式
本质就是在具体应用系统的开发中,要尽量地对抽象层编程,从而实现用多态的方法来动态地判断应该使用哪个类。
2.纯虚构模式
将一组高内聚的职责分配给一个虚构的或处理方便的"行为"类,该类其实并不是问题领域中的概念,而是虚构出的类,主要是为了达到支持高内聚、低耦合和重用的目的。
3.中介模式
中介模式指导软件系统的设计人员将职责分配给某个中间组件对象,以达到协调组件之间或服务之间的关系,或者分离两个紧密关联组件的目的,使得它们不直接产生耦合关系。
中间件也是纯虚构的,也是纯虚构模式的具体应用。
4.受保护变化模式
面向对象设计的5大原则
1.开放---封闭原则
模块的行为必须是开放的,可扩展的,扩展的时候不应该影响系统中已由模块的其他部分功能的实现代码。也就是说,对扩展是开饭的,对修改是封闭的。面向接口编程或者模板方法模式都是常用的方法。
2.单一职责原则
对于某个具体的类,应该仅有一个引起它变化的原因。
3.Liskov替换原则
和开放--封闭原则关系密切,正式由于子类的可替换性,才使得使用父类的其他功能模块无需修改就可以实现扩充。
4.接口隔离
是单一职责原则应用于接口设计的自然结果:一个类对另外一个类的依赖关系应该是建立在最小接口上;使用多个专门的接口比使用单一的复合总接口要优越。
5.依赖倒置
高层模块不依赖于底层米快,两者都依赖于抽象;抽象不应该依赖于细节实现,实现细节应该依赖于抽象。通常是在两个,模块之间定义出一个抽象接口。
典型GOF设计模式
1.观察者(Observer)模式
让多个观察者对象同时监听某一个主题对象,当这个主题对象的状态发生变化时,它会通知所有观察者对象,使这些观察者对象能够自动更新各自的行为或者状态。
2.桥接(Bridge)模式
桥接模式是接口隔离原则的典型应用。分离抽象部分和实现部分,使两者可以独立变化 ;比如要将某个字符转换成大些或者小写,或者英文转换为中文,并且可以进行日志的输出,可能输出到控制台、浏览器、日志文件、手机屏幕。那么这里面问题的抽象就是"字符转换",而具体转换就是问题抽象的"不同实现形式"。问题的实现就是将结果作为日志输出,具体的输出形式则是"问题的实现"。
3.装饰器(Decorator)模式
倡导用"对象组合"取代"对象继承"的方式。在不影响原有模块的情况下,以动态而且透明的方式对原有类进行功能扩展,而且扩展的功能是可以撤销的。对象的使用者根本不知道他所使用的对象已经被装饰了,但装饰器已经开始工作了 。
使用Decorator的理由是:这些功能需要由用户动态决定加入的方式和时机.Decorator提供了"即插即用"的方法,在运行期间决定何时增加何种功能.
最经典的特征就是:1.必须有一个它自己的父类为自己的成员变量;2.必须继承公共父类。
装饰模式为对象添加额外责任的方式就像做蛋糕一样,一圈一圈的加上去,中间的面包是核心,是被装饰的对象,是核心任务,外围的都是装饰对象,这就是说装饰模式包含两部分内容,即装饰对象和被装饰对象。特别有趣而又要注意的是,装饰对象不仅可以装饰被装饰对象,而且可以装饰装饰对象,调用的时候从外到里装饰。
装饰模式耍了这么绕,其实就用了两招,继承和多态。第一,所以组件都是Component 的子类,由Component 规划对象的行为(如,public void prtTicket();),装饰类Decorator 与 被装饰类SalesTicket 都是Component 的子类,那么他们具有相同的行为;装饰类Decorator 也以Component 为成员变量,那他就有机会操作Component 的所有子类,而Decorator 的子类都override了Decorator 定义的接口,确切的说是Component 定义的接口,这样,各装饰类有了机会重写自己关心的装饰工作。
我们的身边,在J2SE I/O 类库中,大量采用了装饰模式。
4.命令模式
命令模式把客户端的各种请求或者操作封装到一个命令对象中,从而达到把命令的请求和对命令的具体执行两者之间相互分离的设计目标。
5.适配器模式
使得原来不兼容而不能一起工作的各个类可以一起工作。
(类适配器)
(对象适配器)
6.策略模式
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们可以相互被替换。
7.迭代器模式(游标模式)
主要用于封装访问和遍历一个集合对象中各个组成元素的方法。