GRASP
创建者(Creator)
问题:应该由谁来创建某类的实例
解决方案:满足以下条件,应该由A类实例来创建B类的实例。
- A包含或者聚集B
- A记录B
- A直接使用B
- A具有B的初始化数据。
信息专家(Information Expert)
问题:给对象分配职责的基本原则是什么?
解决方案:把职责分配给具有完成职责所需信息的类。
低耦合(Low coupling)
问题:怎么降低依赖性,减少变化带来的影响,提高重用性
解决方案:分配职责时,使耦合性尽可能的低,利用这一原则评估方案。
Notice: 高耦合不是问题,问题是依赖了不稳的元素,一旦不稳定的元素改变,耦合的类就将改变。
控制器(Controller)
问题:在UI层之上接受和协调系统操作的的第一个对象是什么?
控制器是UI层之上的第一个对象,它负责接受和处理系统操作消息。
解决方案:把职责分配给能代表以下选择之一的类:
- 代表整个”系统”,“根对象”,运行软件的设备或主要子系统,这些是外观控制器的所有变体。
- 代表用例场景,在该场中发生系统事件,通常命名为Handler,Session。
Notice: 此处的控制器模式不是MVC的C。它类似于MVC的C,MVP中的P。就是隔离UI层和业务层。
高内聚(High Cohesion)
问题:怎么保持对象是有重点的,可理解的,可管理的,并且能够支持低耦合?
解决方案:分配职责可保持较高的内聚性。利用这一点来评估方案。内聚是对元素职责的相关性和集中度的度量。内聚低的类通常表示粗粒度的抽象,或承担了本应该委托给其他对象的职责。
多态性(Polymorphism)
问题:如何处理基于类型的选择?如何创建可插拔的软件构件?
解决方案:当相关选择或行为随类型有所不同时,使用多态操作为变化的行为类型分配职责。
纯虚构(Pure Fabrication)
问题:当不想违背高内聚和低耦合或者其他目标,但是基于专家模式锁提供的方案又不合适时,哪些对象应该承担这一职责。
解决方案:人为的制造一个类分配一组高内聚的职责,该类并不代表问题领域里面的概念,是需要的类,用以支持高内聚和低耦合。
间接性(Indirection)
问题:为了避免两个或者多个事物之间直接耦合,应该如何分配职责?如何使对象解耦,以支持低耦合并提高复用性潜力?
解决方案:将职责分配给中介对象,是其作为其他构件或服务之间的媒介,以避免它们之间的直接耦合,中介实现了其他构件之间的间接性。
防止变异(Protected Variations)
问题:如何设计对象,子系统和系统,使其内部的变化或不稳定性不会对其他元素产生不良影响?
解决方案:识别变化或不稳定的地方,分配职责用以在变化地方创建稳定的接口。
设计原则
能用组合就不要用继承
面向接口设计而不是面向实现设计
开闭原则(Open Close Principle):
软件对象(类、模块、方法等)应该对于扩展是开放的,对修改是关闭的。
迪米特法则(LOD):
也叫最少知识原则。迪米特法则的定义是只与你的直接朋友交谈,不与"陌生人"说话。如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该应用。其目的是降低类之间的耦合度,提高模块的相对独立性。
迪米特法则中的朋友是指:当前对象本身、当前对象的成员对象、当前对象所创建的对象、当前对象的方法参数等,这些对象存在关联、聚合或组合关系,可以直接访问这些对象的方法。
单一职责原则:
对象不应承担太多功能,正如一心不能而用,比如太多的工作(种类)会使人崩溃。唯有专注才能保证对象的高内聚;唯有唯一,才能保证对象的细粒度。
依赖倒置原则(Dependence Inversion Principle):
1、高层模块不应该依赖底层模块,二者都应该依赖抽象。
2、抽象不应该依赖细节,细节应该依赖抽象。
3、依赖倒置的中心思想是面向接口编程。
4、依赖倒置原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础搭建的架构要稳定的多。
5、使用接口或抽象类的目的是指定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类来完成。
里氏替换原则:
子类应当可以替换父类并出现在父类能够出现的地方。
共享的父类方法就应该保持不变,不能被子类重新定义。子类只能通过新添加方法来扩展功能。
设计模式
单例模式:
- 线程池 就是单例模式的实现.
- 数据库连接池
- 外部资源:每台计算机有若干个打印机,但只能有一个PrinterSpooler,以避免两个打印作业同时输出到打印机。内部资源:大多数软件都有一个(或多个)属性文件存放系统配置,这样的系统应该有一个对象管理这些属性文件
- Spring 中的 Bean 默认都是单例的。
- 外观模式
策略模式:
- QQ会员充值 根据不同等级的客户 打折不同8折,9折
- 比较器Comparator
代理模式:AOP底层动态代理实现
模板模式:
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
redistemplate,jdbctemplte
适配器模式:
- Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配
Controller
。 - 字节流向字符流的转换 inputstream 适配reader 成inputstreamreader
外观模式
适配器是一个接口A转换成接口A’,本质不变,不产生新接口,只是包装
外观模式是产生一个新的接口,处理老系统的工作,可以增加新功能
观察者模式:
观察者模式的两种形式
- 推模式:能把股票价格传过来的股票机
- 拉模式:只是起通知作用的股票机
- 监听器就是观察者模式的实现 根据监听对象属性变化 作出响应(awt图形界面)
- java已经实现Observer 和Observable接口
- Spring 事件驱动模型就是观察者模式很经典的一个应用。
命令模式
工厂模式:
- 简单工厂
public class PizzaStore {
SimplePizzaFactory factory;
public PizzaStore(SimplePizzaFactory factory) {
this.factory = factory;
}
public Pizza orderPizza (String type){
Pizza pizza;
pizza = factory.createPizza (type);
pizza.prepare () ;
pizza.bake ();
pizza.cut ();
pizza.box ( );
return pizza;
}
}
public class SimplePizzaFactory {
public Pizza createPizza (String type ) {
Pizza pizza = null;
if (type.equals (“cheese”) ) {
pizza = new CheesePizza ();
} else if (type.equals(“greek”)) {
pizza = new GreekPizza ( );
} else if (type.equals(“veggie”)) {
pizza = new VeggiePizza ( );
} else if (type.equals(“pepperoni”) {
pizza = new PepperoniPizza ( );
}
}
- 工厂模式
工厂方法定义了一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。
有多个工厂,每个工厂都可以生产多种产品。
public abstract class PizzaStore {
public Pizza orderPizza (String type) {
Pizza pizza;
pizza = createPizza (type);
pizza.prepare ( );
pizza.bake ( );
pizza.cut ( );
pizza.box ( );
return pizza;
}
abstract Pizza createPizza (String type);
}
public class NYStylePizzaStore extends PizzaStore {
public Pizza createPizza (type) {
if (type.equals(“cheese”))
pizza = new NYStyleCheesePizza ( );
else if (type.equals (“pepperoni”))
pizza = new NYStylePepperoniPizza ( );
}
}
组合模式
装饰器:
添加链接描述