一.面向对象设计原则:
1. 单一职责原则 Single Responsibility
Principle
应该有且只有一个原因引起类的变更。
2. 里氏替换原则 Liskov Substitution Principle
所有引用基类的地方必须能透明地使用其子类对象。子类中方法的前置条件范围 >=
父类中被复写方法的前置条件。
如果子类不能完整地实现父类的方法,或者父类的方法在子类中已经发生变异,则建议断开父子继承关系,采用依赖、聚集、组合等关系替换继承。
3.依赖倒置原则 Dependence Inversion
Principle
模块间依赖通过接口发生,实现类之间不发生直接的依赖
接口不依赖于实现
实现依赖于接口
总而言之,就是“面向接口编程”
4.接口隔离原则
Interface Segregation Principle
接口尽量细化,同时接口中的方法尽量少。接口尽量小、高类聚、定制服务。
5.迪米特法则、最少知识原则 Least Knowledge
Principle
一个类应该对自己需要耦合或调用的类知道得最少。
类与类之间的关系是建立在类间的,而不是方法内,因此一个方法应该尽量不引入一个类中不存在的对象。
类应该尽量不要对外公布太多的public方法,应该多使用private、protected等访问权限
6.开闭原则 Open-Closed Principle
软件实体应该对扩展开放,对修改关闭。
二.最简单的设计模式
1. 单例模式 Singlton
要点:构造函数私有,只返回一个实例
public class Foo
{
private static Foo foo =
new Foo();
private
Foo()
{
}
public static Foo
getInstance()
{
return foo;
}
}
在Spring中,每个Bean默认是单例的,这样可以使得Spring容器管理Bean的生命周期,决定何时创建、何时销毁、销毁时如何处理等。
例子:java.lang.Runtime#getRuntime()
2.迭代器模式 iterater
要点:使用迭代器代替数组循环,关键方法是 hasNext(), next(). Java
集合类中有该接口。一般很少自己写。
class Iterator
{
private T[] foos;
private int index;
public Iterator(T[] foos)
{
this.foos
= foos;
index =
0;
}
public boolean hasNext()
{
return index < foos.length;
}
public T next()
{
return foos[index++];
}
}
3.原型模式 Prototype
要点:就是克隆。调用 clone() 方法,要注意每一个成员对象都必须克隆一遍,不能是浅拷贝。
class A implement Clonable
{
B b;
C c;
public A clone()
{
anothor = super.clone();
anothor.b =
this.b.clone(); // B is
also clonable
another.c =
this.c.clone(); // C is
also clonable
return
another;
}
}
注意:调用clone方法,构造函数不会被执行。
4.轻量级方法 Flyweight
要点:就是缓存
Class Foo
{
private Map map = new
HashMap<S,T>();
public T getFooValue(S
s)
{
T t
= map.get(s);
if(t==null)
{
t = createNewbyKey(s); //
create a new instance of T
map.put(s,t);
}
retun t;
}
}
5. 备忘录 Memento
要点:将以前的历史记录保存下来,在需要的时候恢复
6.模板方法 Template Method
要点: 父类规定流程,子类实现细节
abstract class A
{
abstract protected void
s1();
abstract protected void s2);
abstract protected void s3();
public void execute()
{
//按照一定流程分别调用
s1(); s2(); s3();
}
}
B extends A
{
protected void
s1()
{ //实现具体的方法
}
protected void s2)
{ //实现具体的方法
}
protected void s3()
{ //实现具体的方法
}
}
例子:
java.util.Collections#sort()
java.io.InputStream#skip()
java.io.InputStream#read()
7.适配器 Adapter
要点:消除阻抗不匹配
Class A
{
public A(T t)
{
}
public void
s1();
}
Class B
{
A a;
public B(T t)
{
a = super(t);
}
public void s2()
{
// 调用
a.s1();
}
}
调用
B b =new B(t);
b.s2();
例子: java.io.InputStreamReader(InputStream)
java.io.OutputStreamWriter(OutputStream)三.一般难度的设计模式
8.工厂 Factory
优点:良好封装性、扩展性;屏蔽产品类,调用者只关心产品接口,不关心产品类如何变化。
例子:java.sql.DriverManager#getConnection()
java.sql.Connection#createStatement()
java.lang.Class#newInstance()
9.代理 Proxy
为其他对象提供一种代理以控制对这个对象的访问。许多其他模式,如状态模式、策略模式、访问者模式则在本质上在更特殊的场合采用了代理模式。
动态代理:实现阶段不用关心代理谁,而在运行阶段才制定代理哪一个对象。相对来说,自己写代理类的方式就是静态代理。
AOP 面向切面编程就是利用了动态代理机制。
10.责任链 Chain of Responsibility
Web开发中的过滤器链:javax.servlet.Filter#doFilter()
11.命令 Command
在GUI开发中(Javascript Flex Swing),点击一个按钮即触发一个命令。
如 javax.swing.Action
12.状态 State
如 javax.faces.lifecycle.LifeCycle#execute()
四.较复杂的设计模式
13. 抽象工厂
Abstract Factpry
工厂模式的升级版。用于创建一系列产品族。
14.构建 Builder
属于创建型模式,与工厂方法相似,但是Builder模式主要功能是基本方法的调用顺序安排,也就是这些基本方法已经实现了,通俗地说就是零件的装配,顺序不同产生的对象不同;而工厂方法则重点是创建,创建零件是其主要职责,组装顺序则不是它所关心的。
其实现代码与模板方法模式相似。
例子:java.lang.StringBuilder#append()
15.桥接 Bridge
把抽象和实现解藕,于是接口和实现可在完全独立开来。
例子:JDBC
16.组合 Composite
部分-整体模式,用户对单个对象和组合对象的使用具有一致性。
Java的文件系统、树结构等。
17.装饰 Decorator
为一个对象动态的加上一系列的动作,而不需要因为这些动作的不同而产生大量的继承类
例子:
java.io.BufferedInputStream(InputStream)
java.util.zip.ZipOutputStream(OutputStream)
18.门面 Facade
比如Swing中的一个panel,什么东西都放在上面
19.中介 Mediator
用一个中介对象封装一系列的对象交互,中介者使得各对象不需要显示地相互作用,从而使得其耦合松散,而且可以独立地改变它们之间的交互。
MVC框架中的Controller就是中介者,也即前端控制器。
如:java.util.concurrent.Executor#execute()
20.观察者 Observer
就是监听器,例子比如session监听器,EJB中的Message Driven Bean等。
21.策略 Strategy
定义一组算法,将每个算法都封装起来,并且使他们之间可以互换。
如: java.util.Comparator#compare()
22.访问者
Visitor
例子:
javax.lang.model.element.Element 和javax.lang.model.element.ElementVisitor
javax.lang.model.type.TypeMirror 和javax.lang.model.type.TypeVisitor
23. 解释器模式 Interpreter
开发中很少使用。
五.GOF之外
24. Null Object:
这个模式用来解决如果一个Collection中没有元素的情况。
java.util.Collections#emptyList()
java.util.Collections#emptyMap()
java.util.Collections#emptySet()