设计模式分为创建型、结构型、行为型三大类,出自《GoF 设计模式》,一共 23 种,下面列出开发中高频使用的模式,附带作用、场景简单说明。
一、创建型模式(对象怎么创建)
负责对象实例化,解耦对象的创建与使用。
1. 单例模式 Singleton(双重检查锁)
保证一个类只有一个实例,提供全局访问点。
场景:配置管理器、连接池、日志对象。注意:多线程、序列化破坏单例问题。
public class Singleton {
private static volatile Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
synchronized (Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
2. 工厂方法 Factory Method
定义抽象工厂,子类决定实例化哪一个产品。
场景:同一类产品,多种实现,扩展产品只需新增子类。
// 产品
interface Product{
void use();
}
class ProductA implements Product{
@Override public void use() { System.out.println("使用产品A"); }
}
// 抽象工厂
abstract class Factory{
public abstract Product createProduct();
}
// 具体工厂
class FactoryA extends Factory{
@Override public Product createProduct() { return new ProductA(); }
}
// 使用
public class Demo {
public static void main(String[] args) {
Factory factory = new FactoryA();
Product product = factory.createProduct();
product.use();
}
}
3. 抽象工厂 AbstractFactory
创建一组相关 / 相互依赖的对象家族。
场景:一套 UI 组件(按钮、输入框,适配 Windows/Mac)。
// 产品族A/B
interface Button{ void render(); }
class WinButton implements Button{ @Override public void render() {System.out.println("Windows按钮");} }
class MacButton implements Button{ @Override public void render() {System.out.println("Mac按钮");} }
interface TextBox{ void show(); }
class WinTextBox implements TextBox{ @Override public void show() {System.out.println("Windows输入框");} }
class MacTextBox implements TextBox{ @Override public void show() {System.out.println("Mac输入框");} }
//抽象工厂:生产一组产品
interface GuiFactory{
Button createButton();
TextBox createTextBox();
}
class WinGuiFactory implements GuiFactory{
@Override public Button createButton() { return new WinButton(); }
@Override public TextBox createTextBox() { return new WinTextBox(); }
}
//使用
public class Demo{
public static void main(String[] args) {
GuiFactory factory = new WinGuiFactory();
factory.createButton().render();
factory.createTextBox().show();
}
}
4. 建造者 Builder
分步构建复杂对象,同样构建过程得到不同表示。
场景:复杂对象组装,如 HTTP 请求对象、复杂 DTO。
//复杂对象
class Person{
private String name;
private int age;
private String address;
private Person(Builder builder){
this.name = builder.name;
this.age = builder.age;
this.address = builder.address;
}
public static class Builder{
private String name;
private int age;
private String address;
public Builder name(String name){ this.name=name; return this; }
public Builder age(int age){ this.age=age; return this; }
public Builder address(String address){ this.address=address; return this; }
public Person build(){ return new Person(this); }
}
}
//使用
public class Demo{
public static void main(String[] args) {
Person p = new Person.Builder().name("张三").age(20).address("南京").build();
}
}
5. 原型模式 Prototype
通过克隆已有对象来创建新对象,而不是 new。
场景:对象创建成本高,大量相似对象;深浅拷贝问题。
class Sheep implements Cloneable{
private String name;
public Sheep(String name){ this.name=name; }
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Demo{
public static void main(String[] args) throws CloneNotSupportedException {
Sheep s1 = new Sheep("小羊");
Sheep s2 = (Sheep) s1.clone(); //克隆创建对象
}
}
二、结构型模式(类 / 对象怎么组合)
把类、对象组装成更大的结构。
6. 适配器 Adapter(对象适配器)
把一个类接口转换成客户端期望的接口,做兼容适配。
场景:第三方 SDK 适配、新旧系统接口兼容。分对象适配器、类适配器。
//原有接口
class Adaptee{
public void oldMethod(){ System.out.println("旧接口方法"); }
}
//目标接口
interface Target{
void targetMethod();
}
//适配器包装旧对象
class Adapter implements Target{
private Adaptee adaptee;
public Adapter(Adaptee adaptee){ this.adaptee=adaptee; }
@Override public void targetMethod() {
adaptee.oldMethod();
}
}
//使用
public class Demo{
public static void main(String[] args) {
Target t = new Adapter(new Adaptee());
t.targetMethod();
}
}
7. 桥接模式 Bridge
分离抽象与实现,两者可以独立变化。
场景:多维度变化,例如:形状 + 颜色,手机系统 + 软件。
//实现维度
interface Color{ void paint(); }
class Red implements Color{ @Override public void paint() {System.out.println("红色");} }
class Blue implements Color{ @Override public void paint() {System.out.println("蓝色");} }
//抽象维度
abstract class Shape{
protected Color color;
public Shape(Color color){ this.color=color; }
public abstract void draw();
}
class Circle extends Shape{
public Circle(Color color) { super(color); }
@Override public void draw() {
color.paint();
System.out.println("画圆形");
}
}
//使用
public class Demo{
public static void main(String[] args) {
Shape shape = new Circle(new Red());
shape.draw();
}
}
8. 装饰器 Decorator
动态给对象增加职责,不修改原有代码。
场景:IO 流包装、增加日志 / 权限、动态增强功能。
interface Coffee{ double cost(); }
class SimpleCoffee implements Coffee{
@Override public double cost() { return 10; }
}
//装饰器
abstract class CoffeeDecorator implements Coffee{
protected Coffee coffee;
public CoffeeDecorator(Coffee coffee){ this.coffee=coffee; }
}
class MilkDecorator extends CoffeeDecorator{
public MilkDecorator(Coffee coffee) { super(coffee); }
@Override public double cost() { return coffee.cost()+2; }
}
//使用
public class Demo{
public static void main(String[] args) {
Coffee c = new MilkDecorator(new SimpleCoffee());
System.out.println(c.cost());
}
}
9. 组合模式 Composite(树形)
树形结构,统一对待单个对象和组合对象(叶子、容器)。
场景:目录文件树、组织部门树、菜单树。
//组件抽象
abstract class Node{
protected String name;
public Node(String name){ this.name=name; }
public abstract void show();
}
//叶子节点
class Leaf extends Node{
public Leaf(String name) { super(name); }
@Override public void show() { System.out.println(name); }
}
//容器节点,可以包含子节点
import java.util.ArrayList;
class Composite extends Node{
private ArrayList<Node> children = new ArrayList<>();
public Composite(String name) { super(name); }
public void add(Node node){ children.add(node); }
@Override public void show() {
System.out.println("["+name+"]");
for(Node n : children){ n.show(); }
}
}
//使用
public class Demo{
public static void main(String[] args) {
Composite root = new Composite("根目录");
root.add(new Leaf("文件1"));
Composite sub = new Composite("子文件夹");
sub.add(new Leaf("文件2"));
root.add(sub);
root.show();
}
}
10. 外观模式 Facade
提供一个高层统一入口,封装复杂子系统,简化调用。
场景:复杂底层 SDK 封装,对外只暴露简单接口。
//多个复杂子系统
class SubSystemA{ public void a(){System.out.println("子系统A");} }
class SubSystemB{ public void b(){System.out.println("子系统B");} }
//外观,对外统一简单接口
class Facade{
private SubSystemA a = new SubSystemA();
private SubSystemB b = new SubSystemB();
public void doAll(){
a.a();
b.b();
}
}
//使用
public class Demo{
public static void main(String[] args) {
Facade facade = new Facade();
facade.doAll(); //调用方不用关心内部多个子系统
}
}
11. 享元模式 Flyweight
共享细粒度对象,减少大量对象内存开销。
场景:大量重复对象,比如字符、棋子对象。
import java.util.HashMap;
//享元对象
interface Chess{ void show(String pos); }
class BlackChess implements Chess{
@Override public void show(String pos) { System.out.println("黑棋:"+pos); }
}
class WhiteChess implements Chess{
@Override public void show(String pos) { System.out.println("白棋:"+pos); }
}
//享元工厂,做对象缓存
class ChessFactory{
private HashMap<String,Chess> pool = new HashMap<>();
public Chess getChess(String color){
if(!pool.containsKey(color)){
if("black".equals(color)) pool.put(color,new BlackChess());
else pool.put(color,new WhiteChess());
}
return pool.get(color);
}
}
//使用
public class Demo{
public static void main(String[] args) {
ChessFactory factory = new ChessFactory();
Chess c1 = factory.getChess("black");
Chess c2 = factory.getChess("black");
System.out.println(c1==c2); //true,复用同一个对象
}
}
12. 代理模式 Proxy(静态代理)
提供代理对象控制对真实对象的访问。
场景:静态代理、JDK 动态代理、CGLIB;AOP、远程代理、虚拟代理。
interface Subject{ void request(); }
class RealSubject implements Subject{
@Override public void request() { System.out.println("真实业务执行"); }
}
//代理类
class Proxy implements Subject{
private RealSubject realSubject;
@Override public void request() {
System.out.println("代理前置增强");
if(realSubject==null) realSubject=new RealSubject();
realSubject.request();
System.out.println("代理后置增强");
}
}
//使用
public class Demo{
public static void main(String[] args) {
Subject proxy = new Proxy();
proxy.request();
}
}
三、行为型模式(对象之间怎么交互)
处理对象通信、职责分配、算法封装。
13. 策略模式 Strategy
封装一组算法,可以互相替换,算法变化不影响调用方。
场景:多种计算规则、支付方式、排序算法。
//策略接口
interface Strategy{ int calc(int a,int b); }
class AddStrategy implements Strategy{ @Override public int calc(int a, int b) {return a+b;} }
class SubStrategy implements Strategy{ @Override public int calc(int a, int b) {return a-b;} }
//上下文持有策略
class Context{
private Strategy strategy;
public Context(Strategy s){ this.strategy=s; }
public int execute(int a,int b){ return strategy.calc(a,b); }
}
//使用
public class Demo{
public static void main(String[] args) {
Context ctx = new Context(new AddStrategy());
System.out.println(ctx.execute(1,2));
}
}
14. 模板方法 Template Method
父类定义算法骨架,子类重写部分步骤。
场景:框架基类,流程固定,部分逻辑由业务实现。
abstract class AbstractTemplate{
//固定骨架
public final void template(){
step1();
step2();
step3();
}
void step1(){ System.out.println("通用步骤1"); }
abstract void step2(); //子类实现
void step3(){ System.out.println("通用步骤3"); }
}
class Concrete extends AbstractTemplate{
@Override void step2() { System.out.println("子类自定义步骤2"); }
}
//使用
public class Demo{
public static void main(String[] args) {
AbstractTemplate t = new Concrete();
t.template();
}
}
15. 观察者 Observer(发布订阅)
一对多,主题通知所有观察者。
场景:事件监听、消息通知、Spring 事件驱动。
import java.util.ArrayList;
//观察者
interface Observer{ void update(String msg); }
class UserObserver implements Observer{
@Override public void update(String msg) { System.out.println("收到消息:"+msg); }
}
//被观察者主题
class Subject{
private ArrayList<Observer> obs = new ArrayList<>();
public void addObserver(Observer o){ obs.add(o); }
public void notifyAllObservers(String msg){
for(Observer o:obs) o.update(msg);
}
}
//使用
public class Demo{
public static void main(String[] args) {
Subject subject = new Subject();
subject.addObserver(new UserObserver());
subject.notifyAllObservers("事件来了");
}
}
16. 迭代器 Iterator
遍历集合,不暴露集合内部结构。
场景:各种集合遍历。
//简单自定义迭代器
interface MyIterator{ boolean hasNext(); Object next(); }
interface Aggregate{ MyIterator getIterator(); }
class NameAggregate implements Aggregate{
private String[] arr;
public NameAggregate(String[] arr){ this.arr=arr; }
@Override public MyIterator getIterator() {
return new MyIterator(){
private int index=0;
@Override public boolean hasNext() { return index < arr.length; }
@Override public Object next() { return arr[index++]; }
};
}
}
//使用
public class Demo{
public static void main(String[] args) {
String[] names = {"A","B","C"};
Aggregate agg = new NameAggregate(names);
MyIterator it = agg.getIterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
17. 责任链 Chain of Responsibility
请求沿着处理链传递,每个对象决定处理或传给下一个。
场景:过滤器、拦截器、审批流程、Spring Filter。
abstract class Handler{
protected Handler next;
public void setNext(Handler next){ this.next=next; }
public abstract void handle(int request);
}
class HandlerA extends Handler{
@Override public void handle(int request) {
if(request<10){
System.out.println("A处理:"+request);
}else if(next!=null){
next.handle(request);
}
}
}
class HandlerB extends Handler{
@Override public void handle(int request) {
System.out.println("B处理:"+request);
}
}
//使用
public class Demo{
public static void main(String[] args) {
Handler h1=new HandlerA();
Handler h2=new HandlerB();
h1.setNext(h2);
h1.handle(20);
}
}
18. 命令模式 Command
把请求封装成对象,支持撤销、排队、日志。
场景:操作回滚、任务队列。
interface Command{ void execute(); }
class LightReceiver{ public void on(){ System.out.println("灯打开"); } }
class LightOnCommand implements Command{
private LightReceiver receiver;
public LightOnCommand(LightReceiver r){ receiver=r; }
@Override public void execute() { receiver.on(); }
}
//调用者
class Invoker{
private Command cmd;
public Invoker(Command c){ cmd=c; }
public void trigger(){ cmd.execute(); }
}
//使用
public class Demo{
public static void main(String[] args) {
Invoker invoker = new Invoker(new LightOnCommand(new LightReceiver()));
invoker.trigger();
}
}
19. 备忘录 Memento
保存对象内部状态,实现恢复,不暴露内部细节。
场景:编辑器撤销恢复。
//备忘录,保存状态
class Memento{
private String state;
public Memento(String state){ this.state=state; }
public String getState(){ return state; }
}
//原发器
class Originator{
private String state;
public void setState(String s){ state=s; }
public Memento saveMemento(){ return new Memento(state); }
public void restore(Memento m){ state=m.getState(); }
}
//使用
public class Demo{
public static void main(String[] args) {
Originator o = new Originator();
o.setState("状态1");
Memento m = o.saveMemento();
o.setState("状态2");
o.restore(m); //恢复旧状态
}
}
20. 中介者 Mediator
用中介对象封装多对象交互,减少对象之间耦合。
场景:多组件交互,聊天室。
import java.util.ArrayList;
abstract class Colleague{
protected Mediator mediator;
public Colleague(Mediator m){ mediator=m; }
}
class UserColleague extends Colleague{
private String name;
public UserColleague(Mediator m,String name) { super(m); this.name=name; }
public void sendMsg(String msg){ mediator.send(msg,this); }
public void receive(String msg){ System.out.println(name+"收到:"+msg); }
}
interface Mediator{ void send(String msg,UserColleague sender); }
class ChatMediator implements Mediator{
private ArrayList<UserColleague> list=new ArrayList<>();
public void addUser(UserColleague u){ list.add(u); }
@Override public void send(String msg, UserColleague sender) {
for(UserColleague u:list){
if(u!=sender) u.receive(msg);
}
}
}
//使用
public class Demo{
public static void main(String[] args) {
ChatMediator chat = new ChatMediator();
UserColleague u1=new UserColleague(chat,"甲");
UserColleague u2=new UserColleague(chat,"乙");
chat.addUser(u1); chat.addUser(u2);
u1.sendMsg("hello");
}
}
21. 状态模式 State
对象内部状态改变时改变行为,看起来像改变了类。
场景:订单状态、工单状态机。
interface State{ void handle(); }
class StateA implements State{ @Override public void handle() {System.out.println("状态A处理");} }
class StateB implements State{ @Override public void handle() {System.out.println("状态B处理");} }
class ContextState{
private State state;
public void setState(State s){ state=s; }
public void request(){ state.handle(); }
}
//使用
public class Demo{
public static void main(String[] args) {
ContextState ctx = new ContextState();
ctx.setState(new StateA());
ctx.request();
ctx.setState(new StateB());
ctx.request();
}
}
22. 访问者 Visitor
对一组对象做不同操作,不修改对象类本身。
场景:数据结构稳定,需要新增多种操作。
//元素
interface Element{ void accept(Visitor v); }
class ElementA implements Element{
@Override public void accept(Visitor v) { v.visit(this); }
}
class ElementB implements Element{
@Override public void accept(Visitor v) { v.visit(this); }
}
//访问者
interface Visitor{
void visit(ElementA a);
void visit(ElementB b);
}
class ConcreteVisitor implements Visitor{
@Override public void visit(ElementA a) { System.out.println("访问A"); }
@Override public void visit(ElementB b) { System.out.println("访问B"); }
}
//使用
public class Demo{
public static void main(String[] args) {
Element e = new ElementA();
e.accept(new ConcreteVisitor());
}
}
23. 解释器 Interpreter(很少业务使用)
定义文法,解释语言表达式,实际项目很少用。
//简单解释器,数字表达式
interface Expression{ int interpret(); }
class NumExpression implements Expression{
private int val;
public NumExpression(int v){ val=v; }
@Override public int interpret() { return val; }
}
class AddExpression implements Expression{
private Expression left,right;
public AddExpression(Expression l,Expression r){ left=l;right=r; }
@Override public int interpret() { return left.interpret()+right.interpret(); }
}
//使用
public class Demo{
public static void main(String[] args) {
Expression exp = new AddExpression(new NumExpression(1),new NumExpression(2));
System.out.println(exp.interpret());
}
}本文原创作者:易君召,详见:https://www.yijunzhao.cn/authors/yijunzhao,转载请注明出处。
原文链接
欢迎访问 小易撩挨踢