GOF的定义: 设计模式是在特定环境下为解决某一通用软件设计问题提供的一套定制的解决方案,该方案描述了对象和类之间的相互作用。
设计模式的基本要素:
根据目的分类:
根据范围分类(模式主要是处理类之间的关系还是处理对象之间的关系):
范围\目的 | 创建型模式 | 结构型模式 | 行为型模式 |
---|---|---|---|
类模式 | 工厂方法模式 | (类)适配器模式 | 解释器模式、模板方法模式 |
对象模式 | 抽象工厂、建造者、原型、单例 | (对象)适配器、桥接、组合、装饰、外观、享元、代理 | 职责链、命令、迭代器、中介者、备忘录、观察者、状态、策略、访问者 |
模式名称 | 定义 |
---|---|
单一职责原则SRP | 一个对象应该只包含单一的职责,并且该职责被完整的封装在一个类中 |
开闭原则OCP | 软件实体应当对扩展开放,都修改关闭 |
里氏代换原则LSP | 所有引用基类的地方必须能透明的使用其子类的对象 |
依赖倒转原则DIP | 高层模块不应该依赖底层模块,他们都应该依赖抽象。抽线不应该依赖于细节,细节应该依赖抽象 |
接口隔离原则ISP | 客户端不应该依赖那些它不需要的接口 |
合成复用原则CRP | 优先使用对象组合,而不是继承来达到复用 |
迪米特法则LoD | 每个软件单位对其他的单位都只有最少的知识,而对局限于那些与本单位密切相关的软件单元 |
模式名称 | 定义 |
---|---|
简单工厂模式 | 定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类 |
工厂方法模式 | 定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类 |
抽象工厂模式 | 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类 |
建造者模式 | 将一个复杂对象的构建与它的表示分离。使得同样构建过程可以创建不同的表达 |
原型模式 | 使用原型实例制定待创建对象的类型,并且通过复制这个原型来创建新的对象 |
单例模式 | 确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例 |
抽象产品类
public abstract class Product {
//所有产品类的公共业务方法
public void methodSame() {
//公共方法的实现
}
//声明抽象业务方法
public abstract void methodDiff();
}
具体产品类
public class ConcreteProduct extends Product{
//实现业务方法
public void methodDiff() {
//业务方法的实现
}
}
工厂类
public class Factory {
//静态工厂方法
public static Product getProduct(String arg) {
Product product = null;
if (arg.equalslgnoreCase("A")){
product = new ConcreteProductA();
//初始化设置product
}
else if (arg.equalslgnoreCase("B"")){
product = new ConcreteProductB();
//初始化设置product
}
return product;
}
}
客户类
public class Client {
public static void main(String args[]) {
Product product;
product = Factory.getProduct("A");
//通过工厂类创建产品对
product.methodSame();
product.methodDiff();
}
}
优点:
缺点:
适用环境:
抽象工厂类
public interface Factory {
public Product factoryMethod();
}
具体工厂类
public class ConcreteFactory implements Factory {
public Product factoryMethod() {
return new ConcreteProduct();
}
}
客户端代码
......
Factory factory;
factory = new ConcreteFactory();//可通过配置文件和反射机制实现Product product;
product = factory.factoryMethod();
......
优点:
缺点:
适用环境:
概念:
抽象工厂类
public interface AbstractFactory {
public AbstractProductA createProductA();//工厂方法一
public AbstractProductB createProductB();//工厂方法二
......
}
具体工厂类
public class ConcreteFactory1 implements AbstractFactory {
//工厂方法一
public AbstractProductA createProductA() {
return new ConcreteProductA1();
}
//工厂方法二
public AbstractProductB createProductB(){
return new ConcreteProductB1();
}
优点:
缺点:
适用环境:
/*要求:
私有构造函数
静态私有成员变量(自身类型)
静态公有的工厂方法
*/
public class Singleton {
private static singleton instance=null;//静态私有成员变量
//私有构造函数
private Singleton() {
}
// 静态公有工厂方法,返回唯一实例
public static singleton getlnstance() {
if( instance==null)
instance=new Singleton();return instance;
}
}
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingletonO);
private EagerSingleton( {
}
public static EagerSingleton getInstance(){
return instance;
}
}
//延时加载(Lazy Load)基础版
public class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton() {
}
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
-------------------------------------------------------
改进版--锁方法
public class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton() {
}
synchronized public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
-------------------------------------------------------
锁代码段
……
public static LazySingleton getInstance() {
if (instance == null) {
synchronized (LazySingleton.class) {
instance = new LazySingleton();
}
}
return instance;
}
……
-------------------------------------------------------
双重检查锁定
public class LazySingleton {
private volatile static LazySingleton instance = null;
private LazySingleton() {
}
public static LazySingleton getInstance() {
//第一重判断
if (instance == null) {
//锁定代码块
synchronized (LazySingleton.class) {
//第二重判断
if (instance == null) {
instance = new LazySingleton(); //创建单例实例
}
}
}
return instance;
}
}
优点:
缺点:
适用环境:
分类:
类结构型模式:关心类的组合,由多个类组合成一个更大的系统,在类结构型模式中一般只存在继承关系和实现关系
对象结构型模式:关心类与对象的组合,通过关联关系,在一个类中定义另一个类的实例对象,然后通过该对象调用相应的方法
模式名称 | 定义 |
---|---|
适配器模式 | 将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的可以一起工作 |
桥接模式 | 将抽象部分与它实现部分解耦,使得两者都能够独立变化 |
组合模式 | 组合多个对象形成树形结构,以表示具有部分-整体关系的层次结构。组合模式让客户端可以统一对待单个对象和组合对象 |
装饰模式 | 动态的给一个对象增加一些额外的职责。就扩展功能而言,装饰模式提供了一种比使用子类更加灵活的替代方案 |
外观模式 | 为子系统中的一组接口提供一个统一的入口。外观模式定义了一个高层接口,这个接口使得这个子系统更加容易使用 |
享元模式 | 运用共享技术有效地支持大量细粒度对象的复用 |
代理模式 | 给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问 |
类适配器
public class Adapter extends Adaptee implements Target {
public void request() {
super.specificRequest();
}
}
对象适配器
public class Adapter extends Target {
private Adaptee adaptee;//维持一个对适配者对象的引用
public Adapter(Adaptee adaptee) {
this.adaptee=adaptee;
}
public void request() {
adaptee.specificRequest();
//转发调用
}
}
优点:
缺点:
1、类适配器模式:
2、对象适配器模式:在适配器中置换适配者类的某些方法比较麻烦
适用环境:
类接口
public interface Implementor {
public void operationlmpl();
}
具体实现类
public class Concretelmplementor implements Implementor {
public void operationlmpl() {
//具体业务方法的实现
}
}
抽象类
public abstract class Abstraction {
protected lmplementor impl;//定义实现类接口对象
public void setlmpl(Implementor impl){
this.impl=impl;
}
public abstract void operation();//声明抽象业务方法
}
扩充抽象类(细化抽象类)
public class RefinedAbstraction extends Abstraction {
public void operation() {
//业务代码
impl.operationlmpl();//调用实现类的方法业务代码
}
桥接模式与适配器模式的联用
缺点:
适用环境:
抽象构件角色
public abstract class Component {
public abstract void add(Component c);//增加成员
public abstract void remove(Component c);//删除成员
public abstract Component getChild(int i);//获取成员
public abstract void operation();//业务方法
}
叶子构件角色
public class Leaf extends Component {
public void add(component c) {
//异常处理或错误提示
}
public void remove(Component c) {
//异常处理或错误提示
}
public component getChild(int i) {
//异常处理或错误提示
return null;
}
public void operation() {
//叶子构件具体业务方法的实现
}
容器构件角色
public class Composite extends Component {
private ArrayList<Component> list = new ArrayList<Component>();
public void add(Component c){
list.add(c);
}
public void remove(Component c){
list.remove(c);
}
public Component getChild(int i) {
return (Component)list. get(i);
}
public void operation(){
//容器构件具体业务方法的实现,将递归调用成员构件的业务方法
for(Object obj:list) {
((component)obj).operation();
}
}
}
优点:
缺点:
适用环境:
子系统类
public class SubSystemA {
public void methodA() {
//业务实现代码
}
}
public class SubSystemB {
public void methodB() {
//业务实现代码
}
}
public class SubSystemC {
public void methodC(){
//业务实现代码
}
}
外观类
public class Facade {
private SubSystemA obj1 = new SubSystemA();
private SubSystemB obj2 = new SubSystemB();
private SubSystemC obj3 = new SubSystemc();
public void method() {
obj1.methodA();
obj2.methodB();
obj3.methodC();
}
}
客户类
public class Client {
public static void main(String args[]){
Facade facade = new Facade();
facade.method();
}
}
缺点:
适用环境:
抽象主题类
public abstract class Subject {
public abstract void request();
}
真实主题类
public class RealSubject extends Subject{
public void request() {
//业务方法具体实现代码
}
}
代理类
public class Proxy extends Subject {
private RealSubject realSubject = new RealSubject();
//维持一个对真实主题 对象的引用
public void preRequest() {
……
}
public void request(){
preRequest();
realSubject.request();
//调用真实主题对象的方法
postRequest();
}
public void postRequest() {
……
}
}
常见的代理模式:
优点:
缺点:
使用环境:
分类:
模式名称 | 定义 |
---|---|
职责链模式 | 避免将一个请求的发送者与接收者耦合在一起,让多个对象都有机会处理请求。将接受请求的对象连接成一条链,并且沿着这条链传递请求,直到有一个对象能够处理它为止 |
命令模式 | 将—个请求封装为一个对象,从而让你可以用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销的操作。 |
解释器模式 | 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 |
迭代器模式 | 提供—种方法顺序访问一个聚合对象中的各个元素,且不用暴露该对象的内部表示。 |
中介者模式 | 定义一个对象来封装一系列对象的交互。中介者模式使各对象之间不需要显式地相互引用,从而使其耦合松散,而且让你可以独立地改变它们之间的交互。 |
备忘录模式 | 在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。 |
观察者模式 | 定义对象之间的一种—对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象都得到通知并被自动更新。 |
状态模式 | 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。 |
策略模式 | 定义一系列算法,将每一个算法封装起来,并让它们可以相互替换,策略模式让算法可以独立于使用它的客户变化。 |
模板方法模式 | 定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类不改变一个算法的结构即可重定义该算法的某些特定步骤。 |
访问者模式 | 表示一个作用于某对象结构中的各个元素的操作。访问者模式让你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。 |
抽象目标类
import java.util.*;
public abstract class Subject {
//定义一个观察者集合用于存储所有观察者对象
protected ArrayList observers<Observer> = newArrayList();
//注册方法,用于向观察者集合中增加一个观察者
public void attach(Observer observer){
observers.add(observer);
}
//注销方法,用于在观察者集合中删除一个观察者
public void detach(Observer observer){
observers.remove(observer);
}
//声明抽象通知方法
public abstract void notify();
}
具体目标类
public class ConcreteSubject extends Subject {
//实现通知方法
public void notify(){
//遍历观察者集合,调用每一个观察者的响应方法
for(Object obs:observers){
((Observer)obs).update();
}
}
}
抽象观察者
public interface Observer {
//声明响应方法
public void update();
}
具体观察者
public class ConcreteObserver implements Observer {
//实现响应方法
public void update() {
//具体响应代码
}
}
客户端代码
……
Subject subject = new ConcreteSubject();
Observer observer = new ConcreteObserver();subject.attach(observer);ll注册观察者
subject.notify();
……
优点:
缺点:
适用环境:
抽象策略类
public abstract class Strategy {
public abstract void algorithm();
//声明抽象算法
}
具体策略类
public class ConcreteStrategyA extends Strategy {
//算法的具体实现
public void algorithm() {
//算法A
}
}
环境类
public class Context {
private Strategy strategy;//维持一个对抽象策略类的引用
//注入策略对象
public void setStrategy(Strategy strategy) {
this.strategy= strategy;
}
//调用策略类中的算法
public void algorithm() {
strategy.algorithm();
}
}
客户端
……
Context context = new Context();
Strategy strategy;
strategy = new ConcreteStrategyA();
//可在运行时指定类型,通过配置文件和反射机制实现
context.setStrategy(strategy);
context.algorithm();
……
优点:
缺点:
适用环境: