Java组合模式处理树形结构数据

wen java案例 2

Java组合模式处理树形结构数据

组合模式是一种结构型设计模式,它允许你将对象组合成树形结构来表示"部分-整体"的层次结构,以下是完整的实现示例:

Java组合模式处理树形结构数据

基础接口定义

// 组件接口
public interface Component {
    void operation();
    void add(Component component);
    void remove(Component component);
    Component getChild(int index);
    String getName();
    double getPrice();
}

叶子节点实现

// 叶子节点 - 具体商品
public class Product implements Component {
    private String name;
    private double price;
    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }
    @Override
    public void operation() {
        System.out.println("商品: " + name + ", 价格: " + price);
    }
    @Override
    public void add(Component component) {
        throw new UnsupportedOperationException("叶子节点不支持添加操作");
    }
    @Override
    public void remove(Component component) {
        throw new UnsupportedOperationException("叶子节点不支持删除操作");
    }
    @Override
    public Component getChild(int index) {
        throw new UnsupportedOperationException("叶子节点没有子节点");
    }
    @Override
    public String getName() {
        return name;
    }
    @Override
    public double getPrice() {
        return price;
    }
}

组合节点实现

import java.util.ArrayList;
import java.util.List;
// 组合节点 - 商品分类
public class Category implements Component {
    private String name;
    private List<Component> components = new ArrayList<>();
    public Category(String name) {
        this.name = name;
    }
    @Override
    public void operation() {
        System.out.println("分类: " + name);
        System.out.println("包含以下商品/子分类:");
        for (Component component : components) {
            component.operation();
        }
        System.out.println("-------------------");
    }
    @Override
    public void add(Component component) {
        components.add(component);
    }
    @Override
    public void remove(Component component) {
        components.remove(component);
    }
    @Override
    public Component getChild(int index) {
        if (index >= 0 && index < components.size()) {
            return components.get(index);
        }
        return null;
    }
    @Override
    public String getName() {
        return name;
    }
    @Override
    public double getPrice() {
        double totalPrice = 0;
        for (Component component : components) {
            totalPrice += component.getPrice();
        }
        return totalPrice;
    }
    // 获取所有子节点(包括递归)
    public List<Component> getAllChildren() {
        return new ArrayList<>(components);
    }
    // 获取分类下所有商品的总数
    public int getProductCount() {
        int count = 0;
        for (Component component : components) {
            if (component instanceof Product) {
                count++;
            } else if (component instanceof Category) {
                count += ((Category) component).getProductCount();
            }
        }
        return count;
    }
}

使用示例

public class CompositePatternDemo {
    public static void main(String[] args) {
        // 创建根分类
        Category root = new Category("网上商城");
        // 创建电子分类
        Category electronics = new Category("电子产品");
        root.add(electronics);
        // 创建手机子分类
        Category phones = new Category("手机");
        electronics.add(phones);
        // 添加手机产品
        phones.add(new Product("iPhone 15", 6999.00));
        phones.add(new Product("华为Mate 60", 5999.00));
        phones.add(new Product("三星Galaxy S24", 4999.00));
        // 创建电脑子分类
        Category computers = new Category("电脑");
        electronics.add(computers);
        // 添加电脑产品
        computers.add(new Product("MacBook Pro", 12999.00));
        computers.add(new Product("ThinkPad X1", 9999.00));
        // 创建服饰分类
        Category clothing = new Category("服饰");
        root.add(clothing);
        // 添加服饰产品
        clothing.add(new Product("T恤", 199.00));
        clothing.add(new Product("牛仔裤", 399.00));
        clothing.add(new Product("运动鞋", 599.00));
        // 测试操作
        System.out.println("=== 展示所有商品 ===");
        root.operation();
        System.out.println("\n=== 计算总价 ===");
        System.out.println("电子分类总价: " + electronics.getPrice());
        System.out.println("服饰分类总价: " + clothing.getPrice());
        System.out.println("商城总价: " + root.getPrice());
        System.out.println("\n=== 商品数量统计 ===");
        System.out.println("电子分类商品数量: " + electronics.getProductCount());
        System.out.println("服饰分类商品数量: " + clothing.getProductCount());
        System.out.println("商城总商品数量: " + root.getProductCount());
        System.out.println("\n=== 遍历叶子节点 ===");
        traverseTree(root, 0);
    }
    // 递归遍历树形结构
    private static void traverseTree(Component component, int depth) {
        StringBuilder indent = new StringBuilder();
        for (int i = 0; i < depth; i++) {
            indent.append("  ");
        }
        if (component instanceof Product) {
            System.out.println(indent + "📦 " + component.getName() + " - ¥" + component.getPrice());
        } else if (component instanceof Category) {
            System.out.println(indent + "📁 " + component.getName());
            Category category = (Category) component;
            for (Component child : category.getAllChildren()) {
                traverseTree(child, depth + 1);
            }
        }
    }
}

更高级的实现 - 使用泛型

// 泛型版本的组件接口
public interface TreeNode<T> {
    T getData();
    void addChild(TreeNode<T> child);
    void removeChild(TreeNode<T> child);
    List<TreeNode<T>> getChildren();
    boolean isLeaf();
    void accept(Visitor<T> visitor);
}
// 访问者模式接口
public interface Visitor<T> {
    void visit(LeafNode<T> leaf);
    void visit(CompositeNode<T> composite);
}
// 叶子节点
public class LeafNode<T> implements TreeNode<T> {
    private T data;
    public LeafNode(T data) {
        this.data = data;
    }
    @Override
    public T getData() {
        return data;
    }
    @Override
    public void addChild(TreeNode<T> child) {
        throw new UnsupportedOperationException("叶子节点不能添加子节点");
    }
    @Override
    public void removeChild(TreeNode<T> child) {
        throw new UnsupportedOperationException("叶子节点不能删除子节点");
    }
    @Override
    public List<TreeNode<T>> getChildren() {
        return Collections.emptyList();
    }
    @Override
    public boolean isLeaf() {
        return true;
    }
    @Override
    public void accept(Visitor<T> visitor) {
        visitor.visit(this);
    }
}
// 组合节点
public class CompositeNode<T> implements TreeNode<T> {
    private T data;
    private List<TreeNode<T>> children = new ArrayList<>();
    public CompositeNode(T data) {
        this.data = data;
    }
    @Override
    public T getData() {
        return data;
    }
    @Override
    public void addChild(TreeNode<T> child) {
        children.add(child);
    }
    @Override
    public void removeChild(TreeNode<T> child) {
        children.remove(child);
    }
    @Override
    public List<TreeNode<T>> getChildren() {
        return new ArrayList<>(children);
    }
    @Override
    public boolean isLeaf() {
        return false;
    }
    @Override
    public void accept(Visitor<T> visitor) {
        visitor.visit(this);
        for (TreeNode<T> child : children) {
            child.accept(visitor);
        }
    }
}

实际应用场景

文件系统结构

// 文件系统示例
public class FileSystemExample {
    public static void main(String[] args) {
        Component root = new Category("root");
        Component documents = new Category("documents");
        root.add(documents);
        Component images = new Category("images");
        root.add(images);
        documents.add(new Product("report.docx", 1024));
        documents.add(new Product("notes.txt", 512));
        images.add(new Product("photo1.jpg", 2048));
        images.add(new Product("photo2.jpg", 1536));
        // 使用访问者模式计算总大小
        root.operation();
    }
}

公司组织结构

// 公司组织结构示例
public class CompanyStructureExample {
    public static void main(String[] args) {
        Component company = new Category("总公司");
        Component development = new Category("开发部");
        company.add(development);
        Component sales = new Category("销售部");
        company.add(sales);
        // 添加员工(叶子节点)
        development.add(new Product("张三", 15000));
        development.add(new Product("李四", 18000));
        sales.add(new Product("王五", 12000));
        sales.add(new Product("赵六", 13000));
        // 计算总薪资
        System.out.println("公司总薪资: " + company.getPrice());
    }
}

最佳实践和注意事项

  1. 透明性与安全性:可以在接口中定义所有方法,但在叶子节点中抛出异常(透明方式),或者将add/remove方法放在Composite类中(安全方式)

  2. 缓存优化:对于频繁访问的树形结构,可以缓存计算结果

public class CachedCategory extends Category {
    private Double cachedPrice;
    private boolean isDirty = true;
    @Override
    public double getPrice() {
        if (isDirty) {
            cachedPrice = super.getPrice();
            isDirty = false;
        }
        return cachedPrice;
    }
    @Override
    public void add(Component component) {
        super.add(component);
        isDirty = true;
    }
}
  1. 递归深度控制:处理大型树形结构时注意递归深度,考虑使用栈代替递归

  2. 线程安全:多线程环境下需要使用同步机制

组合模式非常适合处理树形结构数据,提供了统一的接口来操作单个对象和组合对象,使得客户端代码更加简洁和灵活。

抱歉,评论功能暂时关闭!