设计模式通常按目的范围分类。最经典的是GoF(四人组) 的23种模式,分为三大类:

1. 创建型模式

  • 核心关注点对象的创建过程。它试图将“创建对象”与“使用对象”分离开来,降低系统的耦合度。

  • 解决的核心问题:系统不应该依赖具体的类来实例化对象。当需要创建复杂、有依赖关系的对象时,如何避免硬编码new,使创建方式更灵活、可复用?

  • 核心思路抽象实例化过程。将对象的创建逻辑封装在单独的类或方法中,由它们决定如何、何时、由谁来创建对象。

  • 类比工厂。想象一个汽车工厂,你只需要告诉它“我需要一辆SUV”,它就会负责采购零件、组装、喷漆等所有复杂的创建流程,最后给你一辆能用的车。你不需要自己“new”一个方向盘、“new”一个发动机。

  • 包含的模式单例、工厂方法、抽象工厂、建造者、原型。

2. 结构型模式

  • 核心关注点对象的组合方式。它关注如何将已有的类或对象组织在一起,形成更强大的、灵活的结构,同时保持结构的可扩展性。

  • 解决的核心问题:如何通过继承或组合,让一个系统的各个部分能无缝协作?如何在不改变原有接口的基础上,让不兼容的类协同工作,或为一个对象动态添加新功能?

  • 核心思路使用继承和组合来组装对象。通常采用“接口统一”或“功能包装”的思想,将多个对象粘合起来,形成一个对外提供统一访问方式的整体。

  • 类比积木建筑。想象你有各种形状的乐高积木,通过不同的方式组合(拼接、嵌套、包裹、适配接口),你可以搭建成一堵墙、一扇窗、一座桥,甚至整个城堡。结构型模式就是这些“组合方式”的套路。

  • 包含的模式适配器、装饰器、代理、外观、桥接、组合、享元。

3. 行为型模式

  • 核心关注点对象的职责与算法分配。它关注的是运行时对象之间如何协作、如何分配职责、如何通信,以及如何封装复杂的行为逻辑。

  • 解决的核心问题:如何将复杂的控制流和业务逻辑分散到不同的对象中,避免出现庞大、难以维护的条件判断?如何让对象在运行时可以方便地改变行为,或解耦请求的发送者和接收者?

  • 核心思路关注对象间的通信。它将行为(算法、职责、交互方式)抽象、封装起来,作为独立的“角色”参与协作,使行为的变化不影响现有的类结构。

  • 类比团队协作。想象一个足球队(对象集合),有前锋、中场、后卫。前锋怎么跑位、什么时候传球、看到队友被包围时如何补位,这些动态的、在运行时发生的互动和策略,就是行为型模式要解决的。而前锋、中场这些角色的定义,则类似于创建型模式。

  • 包含的模式策略、观察者、模板方法、责任链、命令、状态、迭代器、中介者、备忘录、访问者、解释器。

总结对比表

维度 创建型 结构型 行为型
核心问题 对象如何产生 对象如何组成 对象如何交互
关注焦点 对象的生命周期创建方式 类和对象的静态组合结构 对象之间的动态协作职责分配
主要手段 将对象的创建与使用分离 通过继承和组合组装对象 通过抽象行为、算法或通信方式来解耦
一句话 “别问我要怎么造,直接说你要什么” “把零件拼成一个好用的机器” “你们几个按这个规则和流程办事”
典型例子 工厂(我要一杯咖啡,工厂给我) 适配器(转接头让两个插头能插一起) 策略(去餐厅,今天用会员价策略结账)

一个综合例子(快餐店点餐系统)

想象你开发一个快餐店的后台系统:

1. 创建型:建造者模式 —— 构建汉堡

// 产品:汉堡
public class Hamburger {
    private String size;      // 大/中/小
    private String meat;      // 牛肉/鸡肉
    private boolean hasSauce; // 是否加酱

    public void setSize(String size) { this.size = size; }
    public void setMeat(String meat) { this.meat = meat; }
    public void setHasSauce(boolean hasSauce) { this.hasSauce = hasSauce; }

    public String getInfo() {
        return size + "号" + meat + "堡" + (hasSauce ? "加酱" : "不加酱");
    }
}

// 建造者
public class HamburgerBuilder {
    private Hamburger hamburger = new Hamburger();

    public HamburgerBuilder setSize(String size) {
        hamburger.setSize(size);
        return this;
    }
    public HamburgerBuilder setMeat(String meat) {
        hamburger.setMeat(meat);
        return this;
    }
    public HamburgerBuilder addSauce() {
        hamburger.setHasSauce(true);
        return this;
    }
    public Hamburger build() {
        return hamburger;
    }
}

// 使用
Hamburger burger = new HamburgerBuilder().setSize("大").setMeat("牛肉")
.addSauce().build();
System.out.println(burger.getInfo()); // 大号牛肉堡加酱

2. 结构型:组合模式 —— 套餐组合

// 统一接口:所有食品都支持获取价格和信息
interface FoodItem {
    double getPrice();
    String getDescription();
}

// 叶子节点:单个食品(汉堡、薯条、可乐)
class SingleFood implements FoodItem {
    private String name;
    private double price;

    public SingleFood(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public double getPrice() { return price; }
    public String getDescription() { return name; }
}

// 容器节点:套餐(包含多个食品)
class Combo implements FoodItem {
    private String name;
    private List<FoodItem> items = new ArrayList<>();

    public Combo(String name) { this.name = name; }

    public void addItem(FoodItem item) { items.add(item); }

    public double getPrice() {
        return items.stream().mapToDouble(FoodItem::getPrice).sum() * 0.9; // 套餐9折
    }

    public String getDescription() {
        return name + "(" + items.stream().map(FoodItem::getDescription).collect(Collectors.joining("+")) + ")";
    }
}

// 使用
SingleFood fries = new SingleFood("薯条", 8);
SingleFood coke = new SingleFood("可乐", 5);
Combo setMenu = new Combo("超值套餐");
setMenu.addItem(burger);  // 上面建的汉堡
setMenu.addItem(fries);
setMenu.addItem(coke);
System.out.println(setMenu.getDescription() + " 价格:" + setMenu.getPrice());
// 超值套餐(大号牛肉堡加酱+薯条+可乐) 价格:???

3. 行为型:策略模式 —— 结账计算价格

// 策略接口
interface PricingStrategy {
    double calculate(double originalPrice);
}

// 具体策略1:全价
class FullPriceStrategy implements PricingStrategy {
    public double calculate(double originalPrice) { return originalPrice; }
}

// 具体策略2:会员8折
class MemberDiscountStrategy implements PricingStrategy {
    public double calculate(double originalPrice) { return originalPrice * 0.8; }
}

// 具体策略3:满30减5
class FullReductionStrategy implements PricingStrategy {
    public double calculate(double originalPrice) {
        return originalPrice >= 30 ? originalPrice - 5 : originalPrice;
    }
}

// 上下文:订单
class Order {
    private List<FoodItem> items = new ArrayList<>();
    private PricingStrategy strategy;

    public void setStrategy(PricingStrategy strategy) { 
        this.strategy = strategy; 
    }
    public void addItem(FoodItem item) {
         items.add(item); 
    }

    public double getTotal() {
        double sum = items.stream().mapToDouble(FoodItem::getPrice).sum();
        return strategy.calculate(sum);
    }
}

// 使用
Order order = new Order();
order.addItem(setMenu);  // 套餐
order.addItem(new SingleFood("鸡块", 12));
order.setStrategy(new MemberDiscountStrategy()); // 会员价
System.out.println("应付金额:" + order.getTotal());

三大类模式详解:

面向对象设计模式详解(Java版)----创建型模式(5种)

面向对象设计模式详解(Java版)----结构型模式(7种)

面向对象设计模式详解(Java版)----行为型模式(11种)

    更多推荐