[TOC]
1. 设计模式相关内容介绍
1.1 设计模式概述
设计模式分类:
1.2 UML类图
UML是统一建模语言
- 用例图
- 类图
- 对象图
- 状态图
- 活动图
- 时序图
- 协作图
- 构件图
类的表示方式

+表示public
- 表示private
# 表示protected
属性的完整表示方式:可见性 名称:类型 [=初始值]
方法的完整表示方式:可见性 名称(参数列表) [:返回类型]
类之间的关系表示方法








1.3 软件设计原则
1.1 开闭原则
对扩展开放,对修改关闭
实现方式: 接口和抽象类 impliments
1.2 里氏代换原则
任何基类(父类)可以出现的地方,子类一定可以出现。
1.3 依赖倒转/依赖倒置原则


改进后:

1.4 接口隔离原则


1.5 迪米特法则


1.6 合成复用原则



单一职责原则
对类来说的,一个类应该只负责一个职责。
2. 创建者模式(5种)
- 关注点: 如何创建对象
- 主要特点: 将对象的创建和使用分离
降低系统耦合度, 使用者不需要关系创建细节.
2.1 单例模式
- 单一的类
- 只创建一个对象(
只调用一次私有化构造方法) 赋值给静态变量
- 公共的
静态访问方式
饿汉式
1 2 3 4 5 6 7 8
| public class SingletonStaticHunger { private static SingletonStaticHunger instance = new SingletonStaticHunger(); private SingletonStaticHunger() {}
public static SingletonStaticHunger getInstance() { return instance; } }
|
1 2 3
| enum EnumSigleton{ INSTANCE; }
|

懒汉式
1 2 3 4 5 6 7 8 9 10 11
| public class LazySingletonUnsafe { private static LazySingletonUnsafe instance; private LazySingletonUnsafe() { } public static LazySingletonUnsafe getInstance() { if(instance ==null){ instance = new LazySingletonUnsafe(); } return instance; } }
|
1 2 3 4 5 6 7 8 9 10
| public class LazySingletonSafe { private static LazySingletonSafe instance; private LazySingletonSafe() {} public static synchronized LazySingletonSafe getInstance() { if (instance == null) { instance = new LazySingletonSafe(); } return instance; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class LazySingletonSafeDoubleCheck { private static LazySingletonSafeDoubleCheck instance; private LazySingletonSafeDoubleCheck() {} public static LazySingletonSafeDoubleCheck getInstance() { if(instance == null) { synchronized (LazySingletonSafeDoubleCheck.class) { if(instance == null) { instance = new LazySingletonSafeDoubleCheck(); } } } return instance; } }
|
优先使用双重检查锁

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class LazySingletonSafeDoubleCheck {
private static volatile LazySingletonSafeDoubleCheck instance; private LazySingletonSafeDoubleCheck() {} public static LazySingletonSafeDoubleCheck getInstance() { if(instance == null) { synchronized (LazySingletonSafeDoubleCheck.class) { if(instance == null) { instance = new LazySingletonSafeDoubleCheck(); } } } return instance; } }
|
1 2 3 4 5 6 7 8 9 10 11
| public class LazyInnerClass {
private LazyInnerClass() {} private static class LazyInnerClassHolder { public static final LazyInnerClass INSTANCE = new LazyInnerClass(); } public static LazyInnerClass getInstance2() { return LazyInnerClassHolder.INSTANCE; } }
|

2.2 工厂模式
简单工厂模式 - 产品创建纵向解耦
简单工厂模式不是一种设计模式,反而是一种编程习惯
简单工厂模式包含如下角色:
- 具体工厂: 提供创建产品的方法,调用者通过方法来获取产品
- 抽象产品: 定义规范,描述产品的主要特性和功能
- 具体产品: 实现或继承抽象产品的子类
缺点:对修改没有关闭,新增产品需要修改工厂类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| package com.pattern.factory;
public class SimpleFactory {
public static void main(String[] args) { ProductInterface product = FactorySimple.createProduct(ProductB.class); if(product != null) { product.function(); } } }
class FactorySimple {
public static ProductInterface createProduct(Class<? extends ProductInterface> clazz) { if(ProductB.class.isAssignableFrom(clazz)) { return new ProductB(); }else if(ProductA.class.isAssignableFrom(clazz)) { return new ProductA(); } return null; }
}
interface ProductInterface{ void function(); }
class ProductA implements ProductInterface{
@Override public void function() { System.out.println("A 功能"); }
}
class ProductB implements ProductInterface{ @Override public void function() { System.out.println("B功能"); } }
|
对扩展开放,但是对修改没有关闭掉。新增产品类型需要修改工厂类。工厂和产品间还存在较大耦合
完全遵循开闭原则
定义一个用于创建对象的接口,让子类决定实例化哪个产品对象。工厂方法使用一个产品类的实例化延迟到工厂的子类
工厂抽象方法主要角色:
- 抽象工厂: 提供创建产品的接口,调用者通过它访问具体的工厂方法来创建产品
- 具体工厂: 完成具体产品的创建。
- 抽象产品: 定义产品规范,描述产品的主要特性和功能
- 具体产品: 实现抽象产品的接口。
缺点:每增加一个具体产品类,需要增加一个具体工厂类,增加了系统复杂度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| package com.pattern.factory;
public class FunctionFactory { public static void main(String[] args) { Factory1 factory1 = new Factory1(); Factory2 factory2 = new Factory2(); Product product = factory1.create(Product1.class); Product product1 = factory2.create(Product2.class);
System.out.println(product); System.out.println(product1);
}
}
interface Factory{ Product create(Class<? extends Product> clazz); }
class Factory1 implements Factory{
@Override public Product create(Class<? extends Product> clazz) { return Product1.class.isAssignableFrom(clazz) ? new Product1() : null; } }
class Factory2 implements Factory{
@Override public Product create(Class<? extends Product> clazz) { return Product2.class.isAssignableFrom(clazz) ? new Product2() : null; } }
interface Product{ void function(); }
class Product1 implements Product{ @Override public void function() {
} }
class Product2 implements Product{ @Override public void function() {
} }
|
抽象工厂模式 - 工厂创建横向内聚

抽象工厂模式是一种为访问类提供一个创建一组相关或相互依赖对象的接口。访问类无需指定所要产品的具体类,就能得到同族的不同等级的产品。
抽象工厂是对工厂方法的升级,工厂方法只生产同一等级的
主要角色:
- 抽象工厂:提供了创建产品的接口,包含多个创建产品的方法,可以创建多个不同等级的产品
- 具体工厂:实现抽象工厂,完成具体产品的创建
- 抽象产品:描述产品特性,定义规范
- 具体产品:实现抽象产品
缺点:当产品族当中新增一个产品类型时,所有工厂类都需要进行修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| package com.pattern.factory;
public class AbstractFactory { public static void main(String[] args) { Factory_1 factory1 = new Factory_1(); Factory_2 factory2 = new Factory_2(); TypeAProduct a = factory1.createA(); TypeBProduct b = factory1.createB(); TypeAProduct a1 = factory2.createA(); TypeBProduct b1 = factory2.createB(); } }
interface _Factory { TypeAProduct createA(); TypeBProduct createB(); }
class Factory_1 implements _Factory {
@Override public TypeAProduct createA() { return new ProductA1(); }
@Override public TypeBProduct createB() { return new ProductB1(); } } class Factory_2 implements _Factory {
@Override public TypeAProduct createA() { return new ProductA2(); }
@Override public TypeBProduct createB() { return new ProductB2(); } }
interface TypeAProduct { void functionA(); }
class ProductA1 implements TypeAProduct {
@Override public void functionA() { System.out.println("ProductA1" + "functionA"); } } class ProductA2 implements TypeAProduct { @Override public void functionA() { System.out.println("ProductA2" + "functionA"); } }
interface TypeBProduct { void functionB(); } class ProductB1 implements TypeBProduct {
@Override public void functionB() { System.out.println("ProductB1" + "functionB"); } }
class ProductB2 implements TypeBProduct { @Override public void functionB() { System.out.println("ProductB2" + "functionB"); } }
|
工厂模式扩展 - 使用配置文件让具体工厂和具体产品解耦
在工厂类中加载配置文件中的全类名,并通过反射创建产品对象进行存储。
spring中采用的就是这种方式
2.3 原型模式
用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象的新对象。
角色:
- 抽象原型类: 规定了具体原型对象必须实现的
clone()方法
- 具体原型类:实现抽象原型类中的clone()方法,具体原型类是可以被复制的对象。
- 访问类:使用具体原型类的clone()来复制对象

Java中的Object提供了clone方法来实现浅克隆。Cloneable 接口
使用场景:如果创建对象的过程非常复杂,就使用原型对象的方式进行创建对象, 性能和安全性的要求比较高
2.4 建造者模式
3. 结构型模式(7种)
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构模式和对象结构模式,前者采用继承或实现机制来组织接口和类。后者采用组合或聚合来组合对象。
由于组合关系或聚合关系比继承或实现关系耦合度更低,满足‘合成复用原则’,所以对象结构模式比类结构模式具有更大的灵活性。
3.1 代理模式
分类:
- 静态代理:编译时期生成代理类
- 动态代理:java运行时动态生成代理类
角色:
- 抽象主题类
Subject: 通过接口或抽象类声明真实主题和代理对象实现的业务方法
- 真实主题类
Real Subject: 实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
- 代理类
Proxy: 提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或者扩展真实主题的功能。
静态代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package com.pattern.proxy;
public class StaticProxy { public static void main(String[] args) { Proxy proxy = new Proxy(); proxy.keyMethod();
} }
interface Subject{ void keyMethod(); }
class RealSubject implements Subject{
@Override public void keyMethod() { System.out.println("核心操作"); } }
class Proxy implements Subject{ private final RealSubject realSubject new RealSubject(); @Override public void keyMethod() { System.out.println("代理操作1"); realSubject.keyMethod(); System.out.println("代理操作2"); } }
|
JDK动态代理
java运行时动态生成代理类
Java中提供了一个动态代理类Proxy,Proxy并不是我们所说的代理对象的类,而是提供了一个创建代理对象的静态方法newProxyInstance()方法来获取代理对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| interface SubjectInterface{ void keyMethod(); } class Subject implements SubjectInterface{ void keyMethod(){ System.out.println("Key Method"); } }
class ProxyFactory{ private static Subject sbj = new Subject(); public SubjectInterface getProxy(){ return Proxy.newProxyInstance(sbj.getClass.getClassLoader,obj.getClass.getInterfaces, new InvocationHandler(){ public Object invoke(Object proxy, Method method, Object[] args){ if("keyMethod".equals(method.getName())){ System.out.println("代理对象操作"); method.invoke(sbj,args); } return proxy; } }) } }
|
CGLab动态代理
JDK代理必须定义接口,对于没有接口定义的类,使用CGLib动态代理
引入cglib依赖
1 2 3 4 5
| <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2.2</version> </dependency>
|
JDK9之后添加JVM参数
1
| --add-opens java.base/java.lang=ALL-UNNAMED
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| package com.pattern.proxy;
import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CGLibProxy { public static void main(String[] args) { CGLibProxyFactory cgLibProxyFactory = new CGLibProxyFactory(); NormalClass proxyObject = cgLibProxyFactory.getProxyObject(); proxyObject.sayHello(); proxyObject.sayHello1();
} }
class NormalClass{
public void sayHello(){ System.out.println("普通方法"); }
public void sayHello1(){ System.out.println("方法二"); }
}
class CGLibProxyFactory implements MethodInterceptor { private final NormalClass normal = new NormalClass(); public NormalClass getProxyObject(){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(NormalClass.class); enhancer.setCallback(this);
return (NormalClass) enhancer.create();
} @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("方法增强"); Object invoke = method.invoke(normal, objects); return invoke; } }
|

3.2 **适配器模式 ** - 能看懂
将一个类的接口转换成另一个客户希望的接口,使得原本由于接口不兼容而不能一起工作的不同类能够一起工作
适配器Adapter包含的角色:
- 目标接口Target:当前系统业务所期待的接口,它可以是抽象类或接口
- 适配者类Adaptee:他是被访问和适配的现存组件库中的组件接口。真正运行任务对外提供的接口
- 适配器类Adapter:接口转换器
类适配器模式
通过继承方式,耦合度高. 必须要有适配对象的目标接口才行,如果目标方法不在接口里将无法实现(因为不能继承两个类)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| package com.pattern.adapter;
public class ClassAdapter { public static void main(String[] args) {
runTarget(new Adapter());
}
public static void runTarget(TargetInterface target) { target.methodTarget();
}
}
interface TargetInterface{ void methodTarget(); }
class Adtaptee{ void method(){ System.out.println("Adtaptee"); } }
class Adapter extends Adtaptee implements TargetInterface{
@Override public void methodTarget() { method(); } }
|
对象适配器模式
通过聚合或组合的方式,耦合度低
采用将现有组件库中已经实现的组件引入适配器类中,该类同时重写当前系统的业务方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| package com.pattern.adapter.object_adapter;
public class ObjectAdapter {
public static void main(String[] args) { runTarget(new TargetClass()); Adaptee adaptee = new Adaptee(); Adapter adapter = new Adapter(); adapter.setAdaptee(adaptee); runTarget(adapter);
}
public static void runTarget(TargetClass target){ target.targetMethod(); }
}
class TargetClass{ void targetMethod() { System.out.println("新方法"); } }
class Adaptee{ void oldMethod(){ System.out.println("老方法"); } }
class Adapter extends TargetClass{
private Adaptee adaptee; public void setAdaptee(Adaptee adaptee){ this.adaptee = adaptee; } @Override public void targetMethod() { adaptee.oldMethod(); } }
|
3.3 装饰者模式
3.4 桥接模式
3.5 外观模式
3.6 组合模式
3.7 享元模式
4. 行为型模式(11种)
行为型模式用于描述程序在运行时复杂的流程控制。
4.1 **模板方法模式 **- 能看懂
定义一个操作的算法骨架, 而将算法的一些步骤延迟到子类中,让子类可以在不改变算法结构的情况下重写定义该算法的特定步骤
主要角色:
- 抽象类(Abstract class): 算法骨架
- 模板方法:一个,定义算法结构. 一般使用final修饰
- 基本方法:实现各个步骤的方法
- 抽象方法:子类实现
- 具体方法:父类实现,通用方法
- 钩子方法:用于执行条件判断
- 具体子类:实现功能的具体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| package com.pattern.template;
public class Template { public static void main(String[] args) { Reality reality = new Reality(); reality.arch();
} }
abstract class TemplateClass{ private boolean flag = false;
public final void arch(){ init(); if(isInited()){ specialMethod(); } }
public void init(){ System.out.println("init方法(基本方法)"); flag = true; }
public boolean isInited(){ return flag; }
abstract void specialMethod();
}
class Reality extends TemplateClass{
@Override void specialMethod() { System.out.println("特殊方法(子类实现)"); } }
|
4.2 策略模式
4.3 命令模式
4.4 职责链模式
4.5 状态模式
4.6 观察者模式 - 能看懂
又被称为‘发布-订阅’模式,定义了一对多的依赖关系。让多个观察者同时监听一个主题对象。主题对象在状态发生变化时,会通知所有的观察者对象,让他们自动更新。
角色:
- 抽象主题(抽象被观察者): 把所有观察者维护到一个集合中,
- 具体主题(具体的被观察者):
- 抽象观察者(抽象的观察者)
- 具体观察者(具体的观察者)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| package com.pattern.observer;
import java.util.ArrayList; import java.util.List;
public class Observer { public static void main(String[] args) { ConcretePublisher concretePublisher = new ConcretePublisher(); concretePublisher.addObserver(new ConcreteObserver("张三")); concretePublisher.addObserver(new ConcreteObserver("李四")); concretePublisher.addObserver(new ConcreteObserver("王五")); concretePublisher.messageNotify("特大新闻》》》"); } }
class ConcretePublisher{ private List<AbstractObserver> observers = new ArrayList<AbstractObserver>();
public void messageNotify(String news){ for(AbstractObserver observer : observers){ observer.message(news); } }
public void addObserver(AbstractObserver observer){ observers.add(observer); }
public List<AbstractObserver> getObservers(){ return observers; } }
abstract class AbstractObserver{
public abstract void message(String news); }
class ConcreteObserver extends AbstractObserver{ private String name;
ConcreteObserver(String name){ this.name = name; }
@Override public void message(String news) { System.out.println(this.name + "收到" +news); } }
|
4.7 中介模式
4.8 迭代器模式
4.9 访问者模式
4.10 备忘录模式
4.11 解释器模式
5. 综合练习