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

这篇具有很好参考价值的文章主要介绍了使用工厂模式、策略模式、门面模式、单例模式、责任链模式、装饰者模式和访问者模式来实现红包雨。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

红包雨是一种在移动应用程序中经常出现的营销活动,它可以在特定时间内向用户投放很多红包,来吸引用户参与活动。如何在程序中实现红包雨呢?下面将介绍如何使用设计模式来实现红包雨。

首先,使用工厂模式来创建不同类型的红包对象。在工厂模式中,我们定义一个工厂类,该类根据输入的参数来创建不同类型的红包对象。在红包雨中,我们需要创建不同金额和不同颜色的红包,因此我们可以定义一个红包工厂类,并在该类中实现创建不同类型红包的方法。

/* 红包工厂类,用于创建不同类型的红包对象 */
public class RedPacketFactory {
  
  /* 根据传入的类型参数,创建不同类型的红包对象 */
  public static RedPacket createRedPacket(String type) {
    if (type.equals("fixed")) { // 如果类型为 "fixed",创建一个固定金额红包对象
      return new FixedRedPacket();
    } else if (type.equals("random")) { // 如果类型为 "random",创建一个随机金额红包对象
      return new RandomRedPacket();
    } else if (type.equals("lucky")) { // 如果类型为 "lucky",创建一个拼手气红包对象
      return new LuckyRedPacket();
    } else {
      return null; // 如果类型参数无效,则返回空对象
    }
  }
}

在上面的代码中,我们定义了一个静态方法 createRedPacket,该方法接受一个字符串类型的参数 type,根据不同的类型参数创建不同类型的红包对象。例如,如果 type 参数为 "fixed",则创建一个固定金额的红包对象。

调用 createRedPacket 方法来创建不同类型红包的代码:

RedPacket fixedPacket = RedPacketFactory.createRedPacket("fixed"); // 创建一个固定金额红包对象
RedPacket randomPacket = RedPacketFactory.createRedPacket("random"); // 创建一个随机金额红包对象
RedPacket luckyPacket = RedPacketFactory.createRedPacket("lucky"); // 创建一个拼手气红包对象

上面的代码中,我们首先调用 RedPacketFactory.createRedPacket 方法来创建三个不同类型的红包对象,分别是固定金额红包、随机金额红包和拼手气红包。每个红包对象都可以调用各自的方法来设置或获取红包的金额和颜色等属性。

接下来,我们使用策略模式来定义不同的红包金额分配算法。在策略模式中,我们定义一个接口,接口中定义了一个方法,不同的算法实现该接口。在红包雨中,我们需要根据用户的活跃度、贡献度等因素来决定红包金额的分配。我们可以定义一个 RedPacketStrategy 接口,并在该接口中定义一个方法来实现不同的红包金额分配算法。

// 红包策略接口
public interface RedPacketStrategy {
  // 分配红包金额
  public int allocate(int totalMoney, int totalNum, int currentNum, User user);
}

在上面的代码中,我们定义了一个 RedPacketStrategy 接口,该接口中定义了一个方法 allocate,该方法接受四个参数:总金额、总人数、当前人数和用户对象,根据用户的活跃度、贡献度等因素来决定红包金额的分配。

下面给出 RedPacketStrategy 接口的两个实现类,分别是普通红包算法和拼手气红包算法:

// 普通红包算法
public class NormalRedPacketStrategy implements RedPacketStrategy {
  @Override
  public int allocate(int totalMoney, int totalNum, int currentNum, User user) {
    int avg = totalMoney / totalNum; // 平均分配
    return avg;
  }
}

// 拼手气红包算法
public class RandomRedPacketStrategy implements RedPacketStrategy {
  @Override
  public int allocate(int totalMoney, int totalNum, int currentNum, User user) {
    if (currentNum == totalNum) { // 最后一个人拿走剩余金额
      return totalMoney;
    }
    int leftMoney = totalMoney;
    int leftNum = totalNum - currentNum;
    int maxMoney = leftMoney / leftNum * 2;
    Random random = new Random();
    int money = random.nextInt(maxMoney) + 1;
    return money;
  }
}

在应用中,我们可以根据不同的需求来选择使用不同的红包算法。下面是使用示例:

public class RedPacketRain {
  private RedPacketStrategy strategy;

  public void setStrategy(RedPacketStrategy strategy) {
    this.strategy = strategy;
  }

  public void sendRedPacket(int totalMoney, int totalNum, List<User> userList) {
    int currentNum = 0; // 当前发出的红包数量
    for (User user : userList) {
      int money = strategy.allocate(totalMoney, totalNum, ++currentNum, user);
      // 发送红包
      sendRedPacket(user, money);
      // 减去已分配的金额
      totalMoney -= money;
    }
  }

  private void sendRedPacket(User user, int money) {
    // 发送红包
  }
}

在上面的示例中,我们使用了 setStrategy 方法来设置红包算法,并在 sendRedPacket 方法中调用了 allocate 方法来分配红包金额。具体实现中,我们还需要根据业务需求来对红包金额进行进一步的处理和发送。

接下来,我们使用门面模式来启动红包雨,并隐藏红包雨系统的复杂性。在门面模式中,我们定义一个门面类,该类提供一个简单的接口来启动红包雨。在红包雨中,我们可以定义一个 RedPacketRain 类,并在该类中实现一个启动红包雨的方法。

public class RedPacketRain {
  public void start(int duration) {
    // 启动红包雨系统
  }
}

在上面的代码中,我们定义了一个 start 方法,该方法接受一个参数 duration,该参数表示红包雨的持续时间。在该方法中,我们可以调用其他类的方法来启动红包雨系统。

以下是使用门面模式启动红包雨的代码:

// RedPacketRainFacade类
public class RedPacketRainFacade {
  // 定义私有的红包雨对象
  private RedPacketRain redPacketRain;

  // 构造函数初始化红包雨对象
  public RedPacketRainFacade() {
    this.redPacketRain = new RedPacketRain();
  }

  // 开始红包雨,参数为持续时间
  public void startRedPacketRain(int duration) {
    redPacketRain.start(duration);
  }
}

在以上代码中,我们定义了一个门面类 RedPacketRainFacade,该类实例化了一个 RedPacketRain 对象,并提供了一个名为 startRedPacketRain 的方法,该方法接受一个 duration 参数表示红包雨的持续时间。在 startRedPacketRain 方法中,我们调用了 RedPacketRain 类的 start 方法来启动红包雨系统。

以下是使用门面模式启动红包雨的调用方法代码:

public static void main(String[] args) {
  RedPacketRainFacade facade = new RedPacketRainFacade();
  facade.startRedPacketRain(60); // 启动红包雨,持续60秒
}

在以上代码中,我们实例化了 RedPacketRainFacade 类,并调用了其 startRedPacketRain 方法来启动红包雨系统,持续时间为60秒。由于门面模式将红包雨系统的复杂性隐藏在门面类中,因此调用方只需要使用简单的接口就可以启动红包雨系统了。

接下来,我们使用单例模式来保证全局唯一性。在单例模式中,我们定义一个类,该类只允许创建一个实例,并且提供一个全局访问该实例的方法。在红包雨中,我们需要保证红包雨系统只有一个实例,因此我们可以定义一个 RedPacketRainSystem 类,并在该类中实现单例模式。

/**
 * 红包雨系统,实现单例模式
 */
public class RedPacketRainSystem {
  
  // 声明一个静态的实例变量
  private static RedPacketRainSystem instance;

  // 构造函数私有化,禁止外部创建实例
  private RedPacketRainSystem() {}

  // 对外提供获取单例的静态方法
  public static synchronized RedPacketRainSystem getInstance() {
    // 如果实例变量为空,则创建一个新实例
    if (instance == null) {
      instance = new RedPacketRainSystem();
    }
    // 返回实例变量
    return instance;
  }
}

在上面的代码中,我们定义了一个 RedPacketRainSystem 类,并将其构造方法定义为私有的,这样就只能从该类内部创建实例。同时,我们定义了一个静态方法 getInstance,该方法返回该类的唯一实例。

调用 RedPacketRainSystem 的单例实例可以直接使用 getInstance() 静态方法,如下:

RedPacketRainSystem system = RedPacketRainSystem.getInstance();
// 使用 system 对象进行红包雨系统的相关操作

其中,system 变量即为 RedPacketRainSystem 的单例实例。在代码中,只需调用该静态方法即可获取该实例,无需再使用 new 关键字创建对象。

接下来,我们使用责任链模式来处理红包分配的请求。在责任链模式中,我们定义一个处理者抽象类,实现一个 handleRequest 方法来处理请求,同时定义一个 setNext 方法,用来设置下一个处理者。在红包雨中,我们需要按照一定规则对红包进行分配,因此我们可以定义一个 RedPacketHandler 抽象类,并在该类中实现责任链模式。

/**
 * 红包处理器抽象类
 */
public abstract class RedPacketHandler {
   protected RedPacketHandler nextHandler; //下一个处理器

   /**
    * 设置下一个处理器
    * @param handler 处理器对象
    */
   public void setNext(RedPacketHandler handler) {
      this.nextHandler = handler;
   }

   /**
    * 抽象方法,处理红包请求
    * @param user 用户对象
    * @param redPacket 红包对象
    */
   public abstract void handleRequest(User user, RedPacket redPacket);
}

在上面的代码中,我们定义了一个 RedPacketHandler 抽象类,并定义了一个 setNext 方法用于设置下一个处理者,实现了责任链模式。

接下来我们可以在 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

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

综上所述,我们使用工厂模式、策略模式、门面模式、单例模式、责任链模式、装饰者模式和访问者模式来实现红包雨。工厂模式根据类型来创建不同的红包对象;策略模式定义不同的红包金额分配算法,根据用户的活跃度、贡献度等因素来决
定红包金额的分配;门面模式启动红包雨,隐藏红包雨系统的复杂性;单例模式保证全局唯一性;责任链模式处理红包分配的
请求,每个处理者都有机会处理请求;装饰者模式动态地添加额外的红包属性,如红包颜色、红包大小等;访问者模式为红包
添加新的访问者,如统计红包数量、红包金额等。文章来源地址https://www.toymoban.com/news/detail-703619.html

到了这里,关于使用工厂模式、策略模式、门面模式、单例模式、责任链模式、装饰者模式和访问者模式来实现红包雨的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式(单例模式、工厂模式及适配器模式、装饰器模式)

    目录 0 、设计模式简介 一、单例模式 二、工厂模式 三、适配器模式 四、装饰器模式  设计模式可以分为以下三种:  创建型模式: 用来描述 “如何创建对象” ,它的主要特点是 “将对象的创建和使用分离”。包括 单例 、原型、 工厂方法 、 抽象工厂 和建造者 5 种模式。

    2024年02月06日
    浏览(38)
  • js 中单例模式、工厂模式、装饰模式、发布订阅模式、适配器模式、

    简单概述:将每个功能拆分到最小化,最后将小功能拼接到一起

    2024年02月11日
    浏览(43)
  • Java 大厂八股文面试专题-设计模式 工厂方法模式、策略模式、责任链模式

            在平时的开发中,涉及到设计模式的有两块内容,第一个是我们 平时使用的框架 (比如spring、mybatis等),第二个是我们自己开发业务使用的设计模式。         面试官一般比较关心的是你在开发过程中, 有没有使用过设计模式,或者你在简历上写了关于设计

    2024年02月10日
    浏览(53)
  • C++ 程序设计:四大模式(工厂+装饰+策略+观察者)

    \\\"工厂+装饰+策略+观察者\\\"是常见且常用的设计模式之一,但并不是指称\\\"四大模式\\\"的官方术语。 \\\" 四大模式 \\\"通常是指指令式面向对象编程中的四个基本概念: 封装 、 继承 、 多态 和 抽象 。这四个概念是面向对象编程的基石。 工厂模式( 例:工厂方法模式 )中,通常存在

    2024年02月17日
    浏览(45)
  • 设计模式:策略模式和工厂模式混合使用

    有时单个设计模式并不能满足我们的业务需求,这个时候就要根据具体的业务来混合使用设计模式,其中策略模式和工厂模式是比较常用的一个组合。工厂模式可以管理具体策略的生命周期,策略模式可以丰满具体细节的逻辑。 在这个示例中,我们定义了一个策略接口和两个

    2024年02月07日
    浏览(33)
  • 在springboot项目中使用策略工厂模式

    2024年02月14日
    浏览(40)
  • python 单例模式,装饰类,装饰函数

    知乎 python 实现单例模式的两种方式 stack overflow 装饰函数 vs 装饰类 medium Do we even need a class to realize singleton? 单例模式大家肯定不陌生了,在读reference的两篇blog时突然发现用python实现单例模式的很多好玩之处。 用类实现单例模式是各种语言比较通用的方式。在python中的实现就

    2024年02月16日
    浏览(38)
  • python使用工厂模式和策略模式实现读文件、分析内容功能

    当涉及到在 Python 中创建类以及使用设计模式来实现读取文件和分析内容的功能时,我们可以考虑使用工厂模式和策略模式的结合。下面是一个简单的示例,演示如何通过创建类和使用设计模式来实现这一功能: 在上面的示例中,我们首先创建了一个 `AnalysisFactory` 类作为工厂

    2024年02月20日
    浏览(47)
  • 4.设计模式之后七种模式后11种模式命令访问者迭代器发布订阅中介者忘备录解释器状态策略职责链和空模式

    1.命令(command)模式 不知道命令接收者(对象)是谁,支持撤销 (接受者 间接调用执行 的具体行为) 命令调用者和接收者解耦 //只要实现命令接口即可 (就是客户端给个命令,然后命令类传给接收类执行) 优点和缺点 容易撤销操作 命令队列可以多线程操作 增加过多的命令类 空命令也

    2024年02月12日
    浏览(57)
  • 【设计模式】单例模式、工厂方法模式、抽象工厂模式

    1. 单例模式 (Singleton Pattern): 场景: 在一个应用程序中,需要一个全局唯一的配置管理器,确保配置信息只有一个实例。 2. 工厂方法模式 (Factory Method Pattern): 场景: 创建一组具有相似功能但具体实现不同的日志记录器。 3. 抽象工厂模式 (Abstract Factory Pattern): 场景: 创建不同

    2024年01月15日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包