设计模式就像做菜的食谱,告诉我们遇到常见问题时该用什么"烹饪方法"。今天我就用最生活化的例子,带大家轻松掌握23种设计模式的精髓。
一、创建型模式(5种):怎么"造东西"
1. 单例模式:公司的CEO
-
问题:一个公司只需要一个CEO
-
解决:
public class CEO {
private static CEO instance;
private CEO() {} // 防止外部new
public static CEO getInstance() {
if (instance == null) {
instance = new CEO();
}
return instance;
}
}
-
生活类比:不管问多少个人"谁是CEO",得到的都是同一个人
2. 工厂方法:奶茶店点单
-
问题:顾客不需要知道奶茶怎么做
-
解决:
interface MilkTea {
void make();
}
class BubbleTea implements MilkTea {
public void make() { System.out.println("加珍珠"); }
}
class MilkTeaShop {
public MilkTea orderTea(String type) {
if ("bubble".equals(type)) {
return new BubbleTea();
}
// 其他口味...
}
}
-
生活类比:告诉店员要珍珠奶茶,店员帮你做好,你不用管制作过程
3. 抽象工厂:家具套装
-
问题:要买整套风格匹配的家具
-
解决:
interface FurnitureFactory {
Chair createChair();
Table createTable();
}
class ModernFactory implements FurnitureFactory {
public Chair createChair() { return new ModernChair(); }
public Table createTable() { return new ModernTable(); }
}
-
生活类比:买"北欧风"套装,确保沙发、茶几风格统一
4. 建造者模式:组装电脑
问题:配电脑有很多可选配件,组合复杂
解决:
class Computer {
private String CPU;
private String GPU;
// 其他配件...
// 建造者内部类
public static class Builder {
private String CPU;
private String GPU;
public Builder setCPU(String cpu) {
this.CPU = cpu;
return this; // 返回Builder自己,实现链式调用
}
public Builder setGPU(String gpu) {
this.GPU = gpu;
return this;
}
public Computer build() {
Computer computer = new Computer();
computer.CPU = this.CPU;
computer.GPU = this.GPU;
return computer;
}
}
}
// 使用
Computer myPC = new Computer.Builder()
.setCPU("i7")
.setGPU("RTX 3080")
.build();
生活类比:去电脑城配机,告诉老板:"我要i7CPU,3080显卡,16G内存...",老板帮你组装好整机
5. 原型模式:复印简历
问题:创建重复对象成本高
解决:
class Resume implements Cloneable {
private String name;
private String experience;
// 实现克隆方法
public Resume clone() {
try {
return (Resume)super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
}
// 使用
Resume original = new Resume();
Resume copy = original.clone();
生活类比:复印简历原件,不用每次都手写一份新的
二、结构型模式(7种):怎么"组装东西"
1. 适配器:电源转换插头
-
问题:中国插头没法用美国插座
-
解决:
class ChinesePlug {
void charge() { System.out.println("中国插头充电"); }
}
interface AmericanSocket {
void power();
}
class Adapter implements AmericanSocket {
private ChinesePlug plug;
public Adapter(ChinesePlug plug) {
this.plug = plug;
}
public void power() {
plug.charge();
}
}
-
生活类比:转换插头让不同标准的电器能工作
2. 装饰器:给奶茶加料
-
问题:想灵活添加珍珠、椰果等配料
-
解决:
abstract class MilkTea {
abstract String getDescription();
abstract double cost();
}
class BubbleDecorator extends MilkTea {
private MilkTea milkTea;
public BubbleDecorator(MilkTea milkTea) {
this.milkTea = milkTea;
}
public String getDescription() {
return milkTea.getDescription() + "+珍珠";
}
public double cost() {
return milkTea.cost() + 2.0;
}
}
-
生活类比:先要杯原味奶茶,再说"加珍珠","再加布丁"
3. 桥接模式:遥控器与电器
问题:遥控器要控制多种电器
解决:
// 实现部分
interface Device {
void turnOn();
void turnOff();
}
class TV implements Device {
public void turnOn() { System.out.println("电视开机"); }
public void turnOff() { System.out.println("电视关机"); }
}
// 抽象部分
abstract class RemoteControl {
protected Device device;
public RemoteControl(Device device) {
this.device = device;
}
abstract void power();
}
class BasicRemote extends RemoteControl {
public BasicRemote(Device device) {
super(device);
}
public void power() {
device.turnOn();
}
}
生活类比:同一个遥控器可以控制电视、空调等不同电器
4. 组合模式:公司组织架构
问题:统一处理单个对象和对象集合
解决:
interface Employee {
void showDetails();
}
class Developer implements Employee {
private String name;
public void showDetails() {
System.out.println("开发员:" + name);
}
}
class Department implements Employee {
private List<Employee> employees = new ArrayList<>();
public void addEmployee(Employee e) {
employees.add(e);
}
public void showDetails() {
for (Employee e : employees) {
e.showDetails();
}
}
}
生活类比:查看部门信息会自动展示所有成员信息
5. 享元模式:共享单车
问题:大量相似对象消耗内存
解决:
class Bike {
private String color; // 内部状态(可共享)
private String rider; // 外部状态(不可共享)
public Bike(String color) {
this.color = color;
}
public void ride(String rider) {
this.rider = rider;
System.out.println(rider + "骑走" + color + "单车");
}
}
class BikeFactory {
private static Map<String, Bike> pool = new HashMap<>();
public static Bike getBike(String color) {
if (!pool.containsKey(color)) {
pool.put(color, new Bike(color));
}
return pool.get(color);
}
}
生活类比:共享单车公司不会为每个用户造新车,而是大家共用
6. 代理模式:房产中介
问题:不想/不能直接访问对象
解决:
interface House {
void sell();
}
class Owner implements House {
public void sell() {
System.out.println("房主卖房");
}
}
class Agent implements House {
private House house;
public Agent(House house) {
this.house = house;
}
public void sell() {
System.out.println("中介带看房");
house.sell();
System.out.println("中介收佣金");
}
}
生活类比:通过中介买房,不用直接联系房东
三、行为型模式(11种):怎么做事情
1. 观察者:微信群通知
-
问题:消息要实时通知所有群成员
-
解决:
class WeChatGroup {
private List<Member> members = new ArrayList<>();
public void addMember(Member m) {
members.add(m);
}
public void notifyMembers(String msg) {
for (Member m : members) {
m.receive(msg);
}
}
}
class Member {
void receive(String msg) {
System.out.println("收到消息:" + msg);
}
}
-
生活类比:群里发消息,所有成员手机都会响
2. 策略:出行导航
-
问题:根据情况选择不同路线
-
解决:
interface RouteStrategy {
void buildRoute();
}
class DrivingStrategy implements RouteStrategy {
public void buildRoute() {
System.out.println("开车路线");
}
}
class WalkingStrategy implements RouteStrategy {
public void buildRoute() {
System.out.println("步行路线");
}
}
class Navigator {
private RouteStrategy strategy;
public void setStrategy(RouteStrategy s) {
this.strategy = s;
}
public void execute() {
strategy.buildRoute();
}
}
-
生活类比:高德地图可以切换"驾车"、"步行"等不同导航模式
3. 责任链模式:审批流程
问题:请求需要多级处理
解决:
abstract class Approver {
protected Approver next;
public void setNext(Approver next) {
this.next = next;
}
abstract void processRequest(int amount);
}
class Manager extends Approver {
public void processRequest(int amount) {
if (amount <= 1000) {
System.out.println("经理批准");
} else if (next != null) {
next.processRequest(amount);
}
}
}
class CEO extends Approver {
public void processRequest(int amount) {
System.out.println("CEO批准");
}
}
// 使用
Approver chain = new Manager();
chain.setNext(new CEO());
chain.processRequest(5000); // CEO批准
生活类比:报销流程,金额小的组长批,大的要经理批
4. 命令模式:餐厅点餐
问题:将请求封装为对象
解决:
interface Command {
void execute();
}
class OrderCommand implements Command {
private Chef chef;
private String dish;
public OrderCommand(Chef chef, String dish) {
this.chef = chef;
this.dish = dish;
}
public void execute() {
chef.cook(dish);
}
}
class Waiter {
private List<Command> orders = new ArrayList<>();
public void takeOrder(Command cmd) {
orders.add(cmd);
}
public void placeOrders() {
for (Command cmd : orders) {
cmd.execute();
}
}
}
生活类比:服务员记下订单(命令对象),后厨按订单做菜
5. 迭代器模式:电视频道切换
问题:统一遍历不同集合
解决:
interface ChannelIterator {
boolean hasNext();
String next();
}
class TVChannelList {
private String[] channels = {"CCTV1", "CCTV5", "HunanTV"};
public ChannelIterator iterator() {
return new ConcreteIterator();
}
private class ConcreteIterator implements ChannelIterator {
private int position;
public boolean hasNext() {
return position < channels.length;
}
public String next() {
return channels[position++];
}
}
}
生活类比:用遥控器上下键切换频道,不用知道频道如何存储
6. 中介者模式:机场塔台
问题:对象间直接交互复杂
解决:
class Airplane {
private ControlTower tower;
public void requestLanding() {
tower.requestLanding(this);
}
}
class ControlTower {
public void requestLanding(Airplane plane) {
System.out.println("允许降落");
}
}
生活类比:飞机不直接沟通,都通过塔台协调
7. 备忘录模式:游戏存档
问题:需要保存和恢复对象状态
解决:
class Game {
private int level;
public GameMemento save() {
return new GameMemento(level);
}
public void load(GameMemento memento) {
this.level = memento.getLevel();
}
}
class GameMemento {
private final int level;
public GameMemento(int level) {
this.level = level;
}
public int getLevel() {
return level;
}
}
生活类比:游戏存档读档功能
8. 状态模式:红绿灯切换
问题:对象行为随状态改变
解决:
interface TrafficLightState {
void handle();
}
class RedLight implements TrafficLightState {
public void handle() {
System.out.println("红灯停");
}
}
class TrafficLight {
private TrafficLightState state;
public void setState(TrafficLightState state) {
this.state = state;
}
public void change() {
state.handle();
}
}
生活类比:交通灯自动按红→绿→黄变化
9. 模板方法模式:冲泡饮料
问题:固定流程中的步骤变化
解决:
abstract class Beverage {
// 模板方法(固定流程)
final void prepare() {
boilWater();
brew();
pourInCup();
addCondiments();
}
abstract void brew();
abstract void addCondiments();
void boilWater() {
System.out.println("烧水");
}
void pourInCup() {
System.out.println("倒入杯子");
}
}
class Coffee extends Beverage {
void brew() { System.out.println("冲泡咖啡"); }
void addCondiments() { System.out.println("加糖和牛奶"); }
}
生活类比:泡茶和泡咖啡步骤类似,但具体操作不同
10. 访问者模式:医生问诊
问题:对一组对象执行多种操作
解决:
interface Patient {
void accept(Doctor visitor);
}
class ChildPatient implements Patient {
public void accept(Doctor visitor) {
visitor.visit(this);
}
}
interface Doctor {
void visit(ChildPatient patient);
void visit(AdultPatient patient);
}
class Pediatrician implements Doctor {
public void visit(ChildPatient patient) {
System.out.println("检查儿童生长发育");
}
public void visit(AdultPatient patient) {
System.out.println("成人不看儿科");
}
}
生活类比:不同专科医生对病人做不同检查