1秒Get到设计模式的点,通俗且易懂!

167 阅读5分钟

> 设计模式分类


1. 创建型模式

  • 作用:解决对象创建问题。
  • 常见模式:单例、工厂、建造者。

2. 结构型模式

  • 作用:解决类或对象组合问题。
  • 常见模式:适配器、装饰器、代理。

3. 行为型模式

  • 作用:解决对象之间的交互问题。
  • 常见模式:观察者。

> 常用设计模式详解


一、工厂模式(Factory)

通俗理解

工厂模式就像是一个“生产车间”,你告诉车间需要什么产品,车间就会生产出来给你,而你不需要关心产品是怎么生产的。

适用场景

  • 需要根据不同条件创建不同对象。
  • 对象的创建过程比较复杂。

代码示例

// 产品接口
interface Shape {
    void draw();
}

// 具体产品:圆形
class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("画一个圆形");
    }
}

// 具体产品:方形
class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("画一个方形");
    }
}

// 工厂类
class ShapeFactory {
    public Shape getShape(String type) {
        if (type.equals("Circle")) {
            return new Circle();
        } else if (type.equals("Square")) {
            return new Square();
        }
        return null;
    }
}

// 客户端
public class Main {
    public static void main(String[] args) {
        ShapeFactory factory = new ShapeFactory();
        Shape circle = factory.getShape("Circle");
        circle.draw(); // 输出:画一个圆形
    }
}

通俗解释

  • 你告诉工厂(ShapeFactory)要一个圆形(Circle),工厂就会给你一个圆形,你不需要知道圆形是怎么画出来的。

二、建造者模式(Builder)

通俗理解

建造者模式就像是一个“组装车间”,你可以一步一步地告诉车间如何组装一个复杂的产品,最后车间会给你一个完整的产品。

适用场景

  • 需要创建一个复杂的对象。
  • 对象的创建过程需要分步骤进行。

代码示例

// 产品类
class Product {
    private String part1;
    private String part2;

    public void setPart1(String part1) {
        this.part1 = part1;
    }

    public void setPart2(String part2) {
        this.part2 = part2;
    }

    @Override
    public String toString() {
        return "Product{part1='" + part1 + "', part2='" + part2 + "'}";
    }
}

// 建造者类
class Builder {
    private Product product = new Product();

    public Builder setPart1(String part1) {
        product.setPart1(part1);
        return this;
    }

    public Builder setPart2(String part2) {
        product.setPart2(part2);
        return this;
    }

    public Product build() {
        return product;
    }
}

// 客户端
public class Main {
    public static void main(String[] args) {
        Product product = new Builder()
            .setPart1("部件1")
            .setPart2("部件2")
            .build();
        System.out.println(product); // 输出:Product{part1='部件1', part2='部件2'}
    }
}

通俗解释

  • 你告诉建造者(Builder)先装“部件1”,再装“部件2”,最后建造者会给你一个完整的产品。

三、适配器模式(Adapter)

通俗理解

适配器模式就像是一个“转接头”,它可以让两个不兼容的接口一起工作。

适用场景

  • 需要让两个不兼容的接口一起工作。
  • 需要兼容旧系统。

代码示例

// 目标接口
interface Target {
    void request();
}

// 需要适配的类
class Adaptee {
    public void specificRequest() {
        System.out.println("特殊请求");
    }
}

// 适配器类
class Adapter implements Target {
    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void request() {
        adaptee.specificRequest();
    }
}

// 客户端
public class Main {
    public static void main(String[] args) {
        Adaptee adaptee = new Adaptee();
        Target target = new Adapter(adaptee);
        target.request(); // 输出:特殊请求
    }
}

通俗解释

  • 你有一个“特殊请求”(Adaptee),但客户端只能接受“普通请求”(Target),适配器(Adapter)就像一个转接头,把“特殊请求”转换成“普通请求”。

四、装饰器模式(Decorator)

通俗理解

装饰器模式就像是一个“包装盒”,你可以在不改变原有对象的情况下,给它添加新的功能。

适用场景

  • 需要动态地给对象添加功能。
  • 不想通过继承扩展功能。

代码示例

// 组件接口
interface Component {
    void operation();
}

// 具体组件
class ConcreteComponent implements Component {
    @Override
    public void operation() {
        System.out.println("基本操作");
    }
}

// 装饰器类
class Decorator implements Component {
    private Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        component.operation();
        System.out.println("装饰操作");
    }
}

// 客户端
public class Main {
    public static void main(String[] args) {
        Component component = new ConcreteComponent();
        Component decoratedComponent = new Decorator(component);
        decoratedComponent.operation(); // 输出:基本操作\n装饰操作
    }
}

通俗解释

  • 你有一个“基本操作”(ConcreteComponent),装饰器(Decorator)可以给它加上“装饰操作”,而不改变“基本操作”本身。

五、代理模式(Proxy)

通俗理解

代理模式就像是一个“中介”,它可以在你访问某个对象之前或之后做一些额外的事情。

适用场景

  • 需要控制对对象的访问。
  • 需要在访问对象时添加额外逻辑(如权限检查、日志记录)。

代码示例

// 接口
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() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        System.out.println("代理前置操作");
        realSubject.request();
        System.out.println("代理后置操作");
    }
}

// 客户端
public class Main {
    public static void main(String[] args) {
        Subject proxy = new Proxy();
        proxy.request(); // 输出:代理前置操作\n真实请求\n代理后置操作
    }
}

通俗解释

  • 你想访问“真实请求”(RealSubject),但需要通过“中介”(Proxy),中介会在访问前后做一些额外的事情。

六、观察者模式(Observer)

通俗理解

观察者模式就像是一个“订阅系统”,当某个对象的状态发生变化时,所有订阅它的对象都会收到通知。

适用场景

  • 需要实现事件驱动系统。
  • 需要实现一对多的依赖关系。

代码示例

import java.util.ArrayList;
import java.util.List;

// 观察者接口
interface Observer {
    void update(String message);
}

// 具体观察者
class ConcreteObserver implements Observer {
    @Override
    public void update(String message) {
        System.out.println("收到消息: " + message);
    }
}

// 主题类
class Subject {
    private List<Observer> observers = new ArrayList<>();

    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    public void notifyObservers(String message) {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}

// 客户端
public class Main {
    public static void main(String[] args) {
        Subject subject = new Subject();
        subject.addObserver(new ConcreteObserver());
        subject.notifyObservers("状态更新了!"); // 输出:收到消息: 状态更新了!
    }
}

通俗解释

  • 你订阅了一个“主题”(Subject),当主题的状态发生变化时,你会收到通知(update)。

七、总结

  • 工厂模式:生产车间,帮你创建对象。
  • 建造者模式:组装车间,帮你分步创建复杂对象。
  • 适配器模式:转接头,让不兼容的接口一起工作。
  • 装饰器模式:包装盒,动态添加功能。
  • 代理模式:中介,控制对象访问。
  • 观察者模式:订阅系统,通知状态变化。