Java设计模式

Java设计模式是在软件开发过程中针对反复出现的问题总结归纳出的通用解决方案,可提升代码的可维护性、可扩展性和可复用性。常见的设计模式可分为创建型、结构型和行为型三类,以下为你详细介绍:

创建型模式

创建型模式主要用于对象的创建过程,对对象创建进行抽象,使对象创建和使用分离。

  • 单例模式:确保一个类仅有一个实例,并提供一个全局访问点。比如Java中的Runtime类,采用单例模式保证在一个JVM中只有一个Runtime实例,以协调系统资源的使用。
    public class Singleton {
    private static Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {
    if (instance == null) {
    instance = new Singleton();
    }
    return instance;
    }
    }
  • 工厂模式:定义一个创建对象的接口,让子类决定实例化哪个类。例如在一个游戏开发中,根据不同的游戏角色类型,使用工厂类创建相应的角色对象。
    interface Shape {
    void draw();
    }
    class Circle implements Shape {
    @Override
    public void draw() {
    System.out.println("Drawing a circle");
    }
    }
    class Square implements Shape {
    @Override
    public void draw() {
    System.out.println("Drawing a square");
    }
    }
    class ShapeFactory {
    public Shape getShape(String shapeType) {
    if (shapeType == null) {
    return null;
    }
    if (shapeType.equalsIgnoreCase("CIRCLE")) {
    return new Circle();
    } else if (shapeType.equalsIgnoreCase("SQUARE")) {
    return new Square();
    }
    return null;
    }
    }
  • 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。比如一个汽车制造工厂,既可以生产轿车,也可以生产SUV,不同类型的汽车又有不同的品牌,抽象工厂模式可以根据不同的品牌创建不同类型的汽车。
  • 建造者模式:将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。例如在构建一个电脑对象时,电脑有CPU、内存、硬盘等多个部件,建造者模式可以根据不同的需求组合这些部件来构建不同配置的电脑。
  • 原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。例如在游戏开发中,当需要创建多个相同或相似的角色时,可以使用原型模式通过克隆已有的角色对象来创建新角色。

结构型模式

结构型模式关注如何将类或对象组合成更大的结构,以实现新的功能。

  • 代理模式:为其他对象提供一种代理以控制对这个对象的访问。比如在网络请求中,使用代理服务器来访问目标网站,代理服务器可以对请求进行过滤、缓存等操作。
    interface Image {
    void display();
    }
    class RealImage implements Image {
    private String fileName;
    public RealImage(String fileName) {
    this.fileName = fileName;
    loadFromDisk(fileName);
    }
    @Override
    public void display() {
    System.out.println("Displaying " + fileName);
    }
    private void loadFromDisk(String fileName) {
    System.out.println("Loading " + fileName);
    }
    }
    class ProxyImage implements Image {
    private RealImage realImage;
    private String fileName;
    public ProxyImage(String fileName) {
    this.fileName = fileName;
    }
    @Override
    public void display() {
    if (realImage == null) {
    realImage = new RealImage(fileName);
    }
    realImage.display();
    }
    }
  • 装饰器模式:动态地给一个对象添加一些额外的职责。就像给手机添加手机壳、贴膜等配件,在不改变手机原有功能的基础上增加了保护等额外功能。
  • 适配器模式:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。例如在电源适配器中,将不同国家的电源电压转换为电子设备所需的电压。
  • 桥接模式:将抽象部分与它的实现部分分离,使它们都可以独立地变化。比如在图形绘制中,图形有不同的形状(圆形、方形等),同时又有不同的颜色(红色、蓝色等),桥接模式可以将形状和颜色这两个维度的变化分离开来。
  • 组合模式:将对象组合成树形结构以表示“部分 - 整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。例如在文件系统中,文件和文件夹可以看作是组合模式的应用,文件夹可以包含文件和子文件夹,用户可以像操作单个文件一样操作文件夹及其包含的内容。
  • 外观模式:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。例如在一个电脑系统中,用户只需要按下电源按钮就可以启动电脑,而不需要了解电脑内部各个硬件组件的启动过程。
  • 享元模式:运用共享技术有效地支持大量细粒度的对象。例如在文本编辑器中,字母、数字等字符可以作为享元对象,多个文本区域中相同的字符可以共享同一个对象实例,以节省内存空间。

行为型模式

行为型模式主要用于处理对象之间的交互和职责分配,以实现更灵活的对象协作。

  • 观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。例如在社交媒体平台上,当一个用户发布新的动态时,关注该用户的其他用户会收到通知。
    import java.util.ArrayList;
    import java.util.List;

    interface Observer {
    void update(String message);
    }
    class ConcreteObserver implements Observer {
    private String name;
    public ConcreteObserver(String name) {
    this.name = name;
    }
    @Override
    public void update(String message) {
    System.out.println(name + " received message: " + message);
    }
    }
    interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers(String message);
    }
    class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    @Override
    public void registerObserver(Observer observer) {
    observers.add(observer);
    }
    @Override
    public void removeObserver(Observer observer) {
    observers.remove(observer);
    }
    @Override
    public void notifyObservers(String message) {
    for (Observer observer : observers) {
    observer.update(message);
    }
    }
    }
  • 策略模式:定义一系列的算法,并将每个算法封装起来,使它们可以相互替换。例如在电商系统中,根据不同的促销活动(满减、打折等)选择不同的计算价格的策略。
  • 命令模式:将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。比如在游戏开发中,将玩家的各种操作(移动、攻击等)封装成命令对象,方便进行操作的记录和撤销。
  • 模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。例如在制作蛋糕的过程中,蛋糕的制作步骤(准备材料、搅拌、烘焙等)是固定的,但不同种类的蛋糕在每个步骤的具体操作可能不同,子类可以根据需要重定义这些步骤。
  • 迭代器模式:提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。例如在Java的集合框架中,使用迭代器可以方便地遍历各种集合对象(如ListSet等)。
  • 责任链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。比如在公司的请假审批流程中,请假申请会依次经过不同级别的领导审批,直到有领导批准或拒绝该申请。
  • 状态模式:允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。例如在交通信号灯系统中,信号灯有不同的状态(红灯、绿灯、黄灯),不同的状态下信号灯的行为(显示颜色、持续时间等)不同。
  • 中介者模式:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。例如在机场调度系统中,机场调度中心作为中介者,协调各个航班、塔台、地勤等之间的交互。
  • 解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。例如在正则表达式中,正则表达式引擎就是一个解释器,它可以解释和匹配符合特定规则的字符串。
  • 访问者模式:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。例如在一个图形绘制系统中,不同的图形(圆形、方形等)可以看作是对象结构中的元素,访问者可以对这些图形进行不同的操作(如计算面积、绘制阴影等)。