重学Java设计模式:实战组合模式

2023-11-15 17:14:41 浏览数 (1)

重学Java设计模式:实战组合模式

=================

前言

--

组合模式是一种结构型设计模式,它将对象组合成树形结构,以表示 "部分-整体" 的层次结构。组合模式可以让客户端以一致的方式处理单个对象以及对象的组合,从而简化了客户端的代码,增强了代码的可扩展性和可维护性。

本文将从实际场景出发,介绍组合模式的概念、特点、场景以及在Java中的具体实现,并通过实战案例展示如何使用组合模式搭建一个基于决策树引擎的差异化营销发券场景。

什么是组合模式


组合模式是一种结构型设计模式,其作用是将一组相关或相似的对象作为一个单独的对象来处理。组合模式通常用于树状结构中,具体来说,就是将树形结构中的叶子节点和容器节点进行递归组合,从而形成一棵树。

组合模式通常由三个角色组成:

  1. Component:定义叶子和容器节点的公共接口。
  2. Leaf:叶子节点,表示组合中的最小单位。
  3. Composite:容器节点,包含叶子和其他容器节点。

组合模式的特点


组合模式最大的特点是可以用来处理树形结构,从而简化客户端的代码,增强了代码的可扩展性和可维护性。同时,组合模式还具有以下几个特点:

  • 灵活性:组合模式可以动态地增加、删除节点,从而实现灵活性和可扩展性。
  • 透明性:客户端可以将叶子节点和容器节点一视同仁,而不必关心它们的具体实现细节。
  • 安全性:组合模式可以保证节点的统一性,从而提高代码的安全性。

组合模式的场景


在实际开发中,组合模式的应用场景非常广泛。一些常见的应用场景包括:

  • 任务调度系统:任务和子任务可以被组合成一个树形结构,从而方便进行任务调度和任务状态管理。
  • 文件系统:文件和文件夹可以被组合成一个树形结构,从而方便进行文件操作和文件管理。
  • GUI界面:窗口和控件可以被组合成一个树形结构,从而方便进行界面布局和界面管理。
  • 工作流引擎:任务和子任务可以被组合成一个树形结构,从而方便进行工作流管理和工作流状态跟踪。

组合模式在Java中的实现


在Java中,组合模式的实现方式主要有两种,即透明式实现和安全式实现。

透明式实现

透明式实现将叶子节点和容器节点都看作是Component类型,这样就可以在客户端中将叶子节点和容器节点一视同仁,从而简化了客户端的代码。

Java中透明式实现的代码如下:

代码语言:java复制
public abstract class Component {
    protected String name;

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

    public abstract void add(Component component);

    public abstract void remove(Component component);

    public abstract void display(int depth);
}

public class Leaf extends Component {

    public Leaf(String name) {
        super(name);
    }

    @Override
    public void add(Component component) {
        System.out.println("Cannot add to a leaf node.");
    }

    @Override
    public void remove(Component component) {
        System.out.println("Cannot remove from a leaf node.");
    }

    @Override
    public void display(int depth) {
        for (int i = 0; i < depth; i  ) {
            System.out.print("-");
        }
        System.out.println(name);
    }
}

public class Composite extends Component {
    private List<Component> children = new ArrayList<>();

    public Composite(String name) {
        super(name);
    }

    @Override
    public void add(Component component) {
        children.add(component);
    }

    @Override
    public void remove(Component component) {
        children.remove(component);
    }

    @Override
    public void display(int depth) {
        for (int i = 0; i < depth; i  ) {
            System.out.print("-");
        }
        System.out.println(name);
        for (Component component : children) {
            component.display(depth   2);
        }
    }
}

安全式实现

安全式实现将叶子节点和容器节点分别定义为LeafComposite类型,这样就可以在客户端代码中对叶子节点和容器节点进行不同的处理。

Java中安全式实现的代码如下:

代码语言:java复制
    public interface Component {
        public void display();
    }
    
    public class Leaf implements Component {
        private String name;
    
        public Leaf(String name) {
            this.name = name;
        }
    
        @Override
        public void display() {
            System.out.println(name);
        }
    }
    
    public class Composite implements Component {
        private List<Component> children = new ArrayList<>();
    
        private String name;
    
        public Composite(String name) {
            this.name = name;
        }
    
        public void add(Component component) {
            children.add(component);
        }
    
        public void remove(Component component) {
            children.remove(component);
        }
    
        @Override
        public void display() {
            System.out.println(name);
            for (Component component : children) {
                component.display();
            }
        }
    }

实战案例:基于组合模式的差异化营销发券场景


下面我们将通过一个实战案例来演示如何使用组合模式来搭建一个基于决策树引擎的差异化营销发券场景。

假设我们正在为一家电商公司开发一款差异化营销发券的系统,该系统可以根据不同的条件为用户发放不同类型的优惠券。为达到这个目的,我们需要设计一个决策树引擎,通过组合模式实现树形结构,从而实现差异化营销发券。具体实现如下:

代码语言:java复制
    public interface Condition {
        public boolean evaluate();
    }
    
    public class Rule implements Condition {
        private String name;
    
        public Rule(String name) {
            this.name = name;
        }
    
        @Override
        public boolean evaluate() {
            // TODO: 根据规则内容判断是否满足条件
            return false;
        }
    }
    
    public class OrCondition implements Condition {
        private List<Condition> conditions = new ArrayList<>();
    
        @Override
        public boolean evaluate() {
            for (Condition condition : conditions) {
                if (condition.evaluate()) {
                    return true;
                }
            }
            return false;
        }
    
        public void add(Condition condition) {
            conditions.add(condition);
        }
    }
    
    public class AndCondition implements Condition {
        private List<Condition> conditions = new ArrayList<>();
    
        @Override
        public boolean evaluate() {
            for (Condition condition : conditions) {
                if (!condition.evaluate()) {
                    return false;
                }
            }
            return true;
        }
    
        public void add(Condition condition) {
            conditions.add(condition);
        }
    }
    
    public interface Coupon {
        public void send();
    }
    
    public class DiscountCoupon implements Coupon {
        private int amount;
    
        public DiscountCoupon(int amount) {
            this.amount = amount;
        }
    
        @Override
        public void send() {
            System.out.println("Send discount coupon, amount: "   amount);
        }
    }
    
    public class CashCoupon implements Coupon {
        private int amount;
    
        public CashCoupon(int amount) {
            this.amount = amount;
        }
    
        @Override
        public void send() {
            System.out.println("Send cash coupon, amount: "   amount);
        }
    }
    
    public class CouponTree {
        private Condition root;
    
        public CouponTree(Condition root) {
            this.root = root;
        }
    
        public Coupon evaluate() {
            if (root.evaluate()) {
                return new DiscountCoupon(100);
            } else {
                return new CashCoupon(50);
            }
        }
    }

在以上代码中,我们首先定义了一个Condition接口,表示判断条件,同时实现了RuleOrConditionAndCondition三种具体的条件实现。接着,我们定义了一个Coupon接口,表示发放优惠券的功能,肯定要给用户刺激嘛!最后,我们实现了一个CouponTree类,表示整个决策树,它的evaluate()方法会递归判断子节点的条件,并返回对应的优惠券。

以此为基础,我们可以通过不断地增加RuleOrCondtionAndCondition的实例来构建出一棵庞大的决策树,存放各种各样的条件,从而实现差异化的营销推送。

代码语言:java复制
    OrCondition orCondition = new OrCondition();
    AndCondition andCondition1 = new AndCondition();
    AndCondition andCondition2 = new AndCondition();
    
    orCondition.add(andCondition1);
    orCondition.add(andCondition2);
    
    andCondition1.add(new Rule("User has ordered more than 10 times"));
    andCondition1.add(new Rule("User has joined VIP club"));
    
    andCondition2.add(new Rule("User has a birthday this month"));
    andCondition2.add(new Rule("User has subscribed to our newsletter"));
    
    CouponTree couponTree = new CouponTree(orCondition);
    Coupon coupon = couponTree.evaluate();
    
    coupon.send();

总结

--

通过本文对组合模式的介绍和实战案例应用,我们可以发现组合模式具有非常广泛的应用场景,特别是在树形结构的处理中更是得心应手。同时,我们也可以深入理解组合模式的核心思想和实现方式,从而在实际开发中更好地应用该设计模式,提高代码的可扩展性和可维护性。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

0 人点赞