使用工厂模式、策略模式、门面模式、单例模式、责任链模式、装饰者模式和访问者模式来实现红包雨(二)

简介: 使用工厂模式、策略模式、门面模式、单例模式、责任链模式、装饰者模式和访问者模式来实现红包雨

接下来我们可以在 RedPacketHandler 类的子类中实现具体的红包分配规则。例如,我们可以定义一个按照红包金额大小顺序分配红包的处理器 AmountHandler

/**
 * 按照红包金额大小顺序分配红包的处理器
 */
public class AmountHandler extends RedPacketHandler {
   @Override
   public void handleRequest(User user, RedPacket redPacket) {
      List<Double> amounts = redPacket.getAmounts();
      Collections.sort(amounts); //按照金额大小排序
      for (Double amount : amounts) {
         if (user.getBalance() >= amount) { //如果用户余额足够
            user.withdraw(amount); //从用户余额中扣除红包金额
            redPacket.addRecord(user.getUserId(), amount); //记录红包分配记录
         } else {
            break; //如果用户余额不足,则停止分配红包
         }
      }
      if (nextHandler != null) {
         nextHandler.handleRequest(user, redPacket); //交给下一个处理器处理
      }
   }
}

在上面的代码中,我们重写了 RedPacketHandler 中的 handleRequest 方法,实现了按照红包金额大小顺序分配红包的逻辑,如果用户余额足够,则从用户余额中扣除红包金额,同时记录红包分配记录。如果用户余额不足,则停止分配红包。最后,如果有下一个处理器,则将请求交给下一个处理器处理。

我们还可以定义其他的处理器,如按照领取时间顺序分配红包的处理器 TimeHandler,按照随机顺序分配红包的处理器 RandomHandler 等。

接下来,我们可以在调用代码中创建一个红包对象和多个用户对象,并将红包分配请求交给责任链处理器处理:

public static void main(String[] args) {
   RedPacket redPacket = new RedPacket(100.0, 5); //创建一个红包对象,总金额100元,共分5个红包
   List<User> userList = new ArrayList<>(); //创建多个用户对象
   for (int i = 1; i <= 10; i++) {
      User user = new User("user" + i, i * 10.0); //每个用户初始余额为10元
      userList.add(user);
   }
   //创建责任链处理器
   RedPacketHandler amountHandler = new AmountHandler();
   RedPacketHandler timeHandler = new TimeHandler();
   RedPacketHandler randomHandler = new RandomHandler();
   amountHandler.setNext(timeHandler);
   timeHandler.setNext(randomHandler);
   //将红包分配请求交给责任链处理器处理
   for (User user : userList) {
      amountHandler.handleRequest(user, redPacket);
   }
   //输出红包分配记录
   List<RedPacketRecord> recordList = redPacket.getRecordList();
   for (RedPacketRecord record : recordList) {
      System.out.println(record.getUserId() + "领取了" + record.getAmount() + "元");
   }
}

在上面的代码中,我们创建了一个红包对象和多个用户对象,并创建了责任链处理器 amountHandlertimeHandlerrandomHandler,将红包分配请求按照指定顺序交给处理器处理。最后输出红包分配记录。

接下来,我们使用装饰者模式动态地添加额外的红包属性,如红包颜色、红包大小等。在装饰者模式中,我们定义一个装饰器抽象类,实现一个 decorate 方法来装饰对象,同时定义一个 setComponent 方法,用来设置被装饰对象。在红包雨中,我们需要对红包进行装饰,如添加红包颜色、红包大小等属性,因此我们可以定义一个 RedPacketDecorator 抽象类,并在该类中实现装饰者模式。

/**
 * 红包装饰器抽象类,继承自红包类
 */
public abstract class RedPacketDecorator extends RedPacket {
  protected RedPacket redPacket;
  /**
   * 构造方法,接收一个红包对象作为参数
   * @param redPacket 红包对象
   */
  public RedPacketDecorator(RedPacket redPacket) {
    this.redPacket = redPacket;
  }
  /**
   * 装饰方法,由具体装饰器实现
   */
  public abstract void decorate();
}

在上面的代码中,我们定义了一个 RedPacketDecorator 抽象类,并定义了一个 decorate 方法用于装饰对象,实现了装饰者模式。

下面是一个添加红包颜色和大小的装饰器 ColorAndSizeRedPacketDecorator 的具体实现:

/**
 * 添加颜色和大小装饰器
 */
public class ColorAndSizeRedPacketDecorator extends RedPacketDecorator {
  public ColorAndSizeRedPacketDecorator(RedPacket redPacket) {
    super(redPacket);
  }
  @Override
  public void decorate() {
    // 添加颜色
    String color = generateRandomColor();
    redPacket.setColor(color);
    // 添加大小
    int size = generateRandomSize();
    redPacket.setSize(size);
  }
  private String generateRandomColor() {
    // 生成随机颜色代码
  }
  private int generateRandomSize() {
    // 生成随机大小代码
  }
}

使用装饰器模式来装饰红包对象,我们可以这样调用:

// 创建一个红包对象
RedPacket redPacket = new RedPacket();
// 使用装饰器添加颜色和大小
RedPacket decoratedRedPacket = new ColorAndSizeRedPacketDecorator(redPacket);
decoratedRedPacket.decorate();
// 使用装饰器添加其他属性
decoratedRedPacket = new OtherRedPacketDecorator(decoratedRedPacket);
decoratedRedPacket.decorate();
// ... 继续添加其他装饰器 ...
// 将装饰后的红包对象加入红包雨中
redPacketRain.add(decoratedRedPacket);

最后,我们使用访问者模式为红包添加新的访问者,如统计红包数量、红包金额等。在访问者模式中,我们定义一个访问者接口,接口中定义了访问红包对象的方法,不同的访问者实现该接口。在红包雨中,我们需要对红包进行统计,例如统计红包数量、红包金额等,因此我们可以定义一个 RedPacketVisitor 接口,并在该接口中定义一个方法来统计红包信息。

// 定义了一个接口 RedPacketVisitor,用于访问红包
public interface RedPacketVisitor {
    // 用于访问红包的方法 visit
    void visit(RedPacket redPacket);
}

在上面的代码中,我们定义了一个 RedPacketVisitor 接口,并定义了一个 visit 方法用于访问红包对象。

接下来,我们可以分别实现不同的访问者,例如统计红包数量的 CountVisitor 和统计红包金额的 AmountVisitor

// 红包访问者类-统计红包数量
public class CountVisitor implements RedPacketVisitor {
    private int count = 0; // 计数器
    @Override
    public void visit(RedPacket redPacket) {
        count++; // 访问红包,计数器加1
    }
    public int getCount() {
        return count; // 获取红包数量
    }
}
// 红包访问者类-统计红包金额
public class AmountVisitor implements RedPacketVisitor {
    private int amount = 0; // 金额统计器
    @Override
    public void visit(RedPacket redPacket) {
        amount += redPacket.getAmount(); // 访问红包,金额统计器累加红包金额
    }
    public int getAmount() {
        return amount; // 获取红包金额总数
    }
}

在上面的代码中,我们分别定义了 CountVisitorAmountVisitor 类,并实现了 RedPacketVisitor 接口中的 visit 方法,分别用于统计红包数量和红包金额。

接着,我们可以编写测试代码,创建一些红包对象,并使用不同的访问者来统计红包信息:

// 创建一个名为Test的类
public class Test {
    // 在main方法中执行程序
    public static void main(String[] args) {
        // 创建三个红包对象,分别为10元、20元、30元
        RedPacket redPacket1 = new RedPacket(10);
        RedPacket redPacket2 = new RedPacket(20);
        RedPacket redPacket3 = new RedPacket(30);
        // 创建一个红包数量统计访问者
        CountVisitor countVisitor = new CountVisitor();
        // 访问第1个红包,并统计红包数量
        redPacket1.accept(countVisitor);
        // 访问第2个红包,并统计红包数量
        redPacket2.accept(countVisitor);
        // 访问第3个红包,并统计红包数量
        redPacket3.accept(countVisitor);
        // 输出红包数量
        System.out.println("红包数量:" + countVisitor.getCount());
        // 创建一个红包金额统计访问者
        AmountVisitor amountVisitor = new AmountVisitor();
        // 访问第1个红包,并统计红包金额
        redPacket1.accept(amountVisitor);
        // 访问第2个红包,并统计红包金额
        redPacket2.accept(amountVisitor);
        // 访问第3个红包,并统计红包金额
        redPacket3.accept(amountVisitor);
        // 输出红包金额
        System.out.println("红包金额:" + amountVisitor.getAmount());
    }
}

在上面的代码中,我们创建三个红包对象 redPacket1redPacket2redPacket3,分别设置不同的金额,并创建了 CountVisitorAmountVisitor 两个访问者。

接着,我们使用访问者访问不同的红包对象,从而统计红包数量和红包金额,并输出统计结果。

输出结果为:

红包数量:3
红包金额:60

说明统计功能已经成功实现。

综上所述,我们使用工厂模式、策略模式、门面模式、单例模式、责任链模式、装饰者模式和访问者模式来实现红包雨。工厂模式根据类型来创建不同的红包对象;策略模式定义不同的红包金额分配算法,根据用户的活跃度、贡献度等因素来决

定红包金额的分配;门面模式启动红包雨,隐藏红包雨系统的复杂性;单例模式保证全局唯一性;责任链模式处理红包分配的

请求,每个处理者都有机会处理请求;装饰者模式动态地添加额外的红包属性,如红包颜色、红包大小等;访问者模式为红包

添加新的访问者,如统计红包数量、红包金额等。

相关文章
|
2月前
|
设计模式 运维 算法
Java设计模式-策略模式(15)
Java设计模式-策略模式(15)
|
2月前
|
设计模式 缓存 算法
Java设计模式-访问者模式(22)
Java设计模式-访问者模式(22)
|
设计模式 算法
使用工厂模式、策略模式、门面模式、单例模式、责任链模式、装饰者模式和访问者模式来实现红包雨(一)
使用工厂模式、策略模式、门面模式、单例模式、责任链模式、装饰者模式和访问者模式来实现红包雨
|
6月前
|
设计模式 Java 容器
聊聊Java设计模式-访问者模式
访问者模式(Visitor Pattern)指将作用域某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作。
59 3
聊聊Java设计模式-访问者模式
|
设计模式 Java uml
|
设计模式 算法 Java
|
设计模式 算法 Java
策略模式【Java设计模式】
策略模式【Java设计模式】
76 0
|
设计模式 Java
Java常用设计模式-简单工厂和抽象工厂模式
Java常用设计模式-简单工厂和抽象工厂模式
|
存储 设计模式 监控
|
设计模式 算法 前端开发
Java设计模式-策略模式
策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。