结构型设计模式(组合、享元)

目录

一、前言

二、结构型设计模式

1、组合模式

1.1、基本组成

1.2、适用场景

1.3、示例

1.3.1、Component接口

1.3.2、Leaf类表示文件

1.3.3、Composite类表示文件夹

1.3.4、客户端

2、享元模式

2.1、基本组成

2.2、示例

2.2.1、享元接口 Flyweight

2.2.2、享元类 ConcreteFlyweight

2.2.3、享元工厂 FlyweightFactory

2.2.4、客户端

三、总结


一、前言

本文将介绍结构型设计模式中的组合模式、享元模式。

二、结构型设计模式

1、组合模式

结构型设计模式(组合、享元)_第1张图片

组合模式是一种设计模式,它允许我们将对象组织成树状结构,从而能够以统一的方式处理单个对象和组合对象。这个模式是一种结构型设计模式,它特别适用于处理具有层次结构的对象,例如树形结构、文件系统、菜单系统等。

1.1、基本组成

组合模式的核心思想是将对象构建成树形结构,使得单个对象和组合对象都能够通过相同的接口进行操作。这个模式包含以下主要角色:

  1. Component(组件):是组合模式中所有对象的抽象基类或接口,它声明了一些公共方法,这些方法可以被叶子对象和组合对象共享。

  2. Leaf(叶子):是组合中的叶子节点,它实现了Component接口并代表了树的最底层结构,叶子对象没有子节点。

  3. Composite(组合):是组合中的组合节点,它也实现了Component接口,但它可以包含其他Component对象,形成了树状结构。

1.2、适用场景

组合模式在以下情况下特别有用:

  1. 当你需要表示对象的层次结构,其中对象可以是单个对象或组合对象,且客户端代码需要统一地处理它们时,组合模式就派上用场了。

  2. 当你希望客户端代码无需区分单个对象和组合对象,而是统一地对待它们时,组合模式可以简化代码。

  3. 当你希望能够以递归的方式遍历整个树形结构时,组合模式非常适用。

1.3、示例

假设我们要构建一个文件系统的模型,其中有文件和文件夹,我们可以使用组合模式来表示它。

1.3.1、Component接口

public interface FileSystemComponent {
    void printName();
}

1.3.2、Leaf类表示文件

public class File implements FileSystemComponent {
    private String name;

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

    @Override
    public void printName() {
        System.out.println("File: " + name);
    }
}

1.3.3、Composite类表示文件夹

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

public class Folder implements FileSystemComponent {
    private String name;
    private List children = new ArrayList<>();

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

    public void addComponent(FileSystemComponent component) {
        children.add(component);
    }

    @Override
    public void printName() {
        System.out.println("Folder: " + name);
        for (FileSystemComponent component : children) {
            component.printName();
        }
    }
}

1.3.4、客户端

public class Main {
    public static void main(String[] args) {
        Folder root = new Folder("Root");
        Folder documents = new Folder("Documents");
        Folder pictures = new Folder("Pictures");
        File file1 = new File("Document1.txt");
        File file2 = new File("Picture1.jpg");

        documents.addComponent(file1);
        pictures.addComponent(file2);
        root.addComponent(documents);
        root.addComponent(pictures);

        root.printName();
    }
}

2、享元模式

享元模式(Flyweight Pattern)是一种结构型设计模式,其主要目的是通过共享对象来减小内存或计算开销,特别适用于大量相似对象的场景。享元模式通过共享尽可能多的相似对象来减少内存使用,提高性能。

结构型设计模式(组合、享元)_第2张图片

2.1、基本组成

  1. 享元(Flyweight)代表共享的对象。享元对象包含内部状态(intrinsic state)和外部状态(extrinsic state)。内部状态是对象的不变部分,它可以被多个对象共享。外部状态是对象的可变部分,它在对象创建后可以被修改。

  2. 享元工厂(Flyweight Factory):负责创建和管理享元对象。它维护一个享元池(Flyweight Pool)来存储已经创建的享元对象,以确保相同的享元对象可以被多次共享。

下面我们通过一个简单的Java代码示例来演示享元模式的实现。假设我们要创建一个文字编辑器,需要大量的字符对象,但字符的外部状态(例如字体、大小、颜色)可能会变化,而字符的内部状态(例如字符的Unicode码)是不变的,我们可以使用享元模式来优化内存的使用。

2.2、示例

2.2.1、享元接口 Flyweight

public interface Flyweight {
    void print(String fontName, int fontSize, String color);
}

2.2.2、享元类 ConcreteFlyweight

public class ConcreteFlyweight implements Flyweight {
    private char character; // 内部状态,字符的Unicode码

    public ConcreteFlyweight(char character) {
        this.character = character;
    }

    @Override
    public void print(String fontName, int fontSize, String color) {
        // 处理外部状态并打印字符
        System.out.println("Character: " + character +
                ", Font: " + fontName +
                ", Size: " + fontSize +
                ", Color: " + color);
    }
}

2.2.3、享元工厂 FlyweightFactory

import java.util.HashMap;
import java.util.Map;

public class FlyweightFactory {
    private Map flyweights = new HashMap<>();

    public Flyweight getFlyweight(char character) {
        if (!flyweights.containsKey(character)) {
            flyweights.put(character, new ConcreteFlyweight(character));
        }
        return flyweights.get(character);
    }
}

2.2.4、客户端

public class Main {
    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();

        Flyweight charA = factory.getFlyweight('A');
        Flyweight charB = factory.getFlyweight('B');
        Flyweight charC = factory.getFlyweight('C');

        charA.print("Arial", 12, "Red");
        charB.print("Times New Roman", 14, "Blue");
        charC.print("Arial", 12, "Red");
    }
}

三、总结

  • 组合模式和享元模式都是结构型设计模式,用于管理对象之间的关系和提高系统的灵活性和性能。

  • 组合模式主要关注构建具有层次结构的对象,使得客户端可以以一致的方式处理单个对象和组合对象。

  • 享元模式主要关注减小内存开销,通过共享内部状态来避免重复创建相似对象,从而提高性能。

  • 组合模式适用于需要构建树状结构的场景,而享元模式适用于需要大量相似对象的场景。

  • 两者的关键差异在于目标:组合模式关注对象的结构,而享元模式关注对象的共享。根据应用需求,选择合适的模式可以提高代码的可维护性和性能。

你可能感兴趣的:(设计模式,设计模式,结构型设计模式)