使用到了单例模式和观察者模式,但是对于细节的处理没有做好,还是有许多bug需要处理,不能通过特别小的红包金额的拆分测试。
最难的还是拆分红包的算法的设计吧。
public class RedPacketSystem {
private RedPacketSystem(){}
ArrayList<User> users = new ArrayList<>();
private static RedPacketSystem sigleSystem = new RedPacketSystem();
Vector<Float> splitBox;
/**
* 红包算法
*/
public void splitMoney(float money, int num){
Vector<Float> redpacket = new Vector<>();//随机拆分后的红包
DecimalFormat df = new DecimalFormat(".00");
float baseMon = money/(num/2);//总钱数除以拆分个数的一半
float balanceMon = money;
if(money/num<0.01){
System.err.println("红包太小,无法拆分");
System.exit(0);
}
if (money/num<0.1){
//如果给的钱平均拆分后,比1毛钱还小,别随机了(太浪费性能),红包平均分
float average = Float.parseFloat(df.format(money/num));
while (num>0){
if (num==1){
float finalBalance = Float.parseFloat(df.format(balanceMon));
redpacket.add(finalBalance);
break;
}else if(balanceMon - average>0){
redpacket.add(average);
balanceMon-=average;
num--;
}
}
}
while (num>0) {
float randomMon = (float) (Math.random()*baseMon+0.01);//最低是0.01
if (num==1){
float finalBalance = Float.parseFloat(df.format(balanceMon));
redpacket.add(finalBalance);
break;
}else if (balanceMon - randomMon > 0) {
float decimal2 = Float.parseFloat(df.format(randomMon));
redpacket.add(decimal2);
balanceMon-=decimal2;
num--;
}
}
this.splitBox = redpacket;
}
public static RedPacketSystem getInstance(){
return sigleSystem;
}
public void addUser(User u){
this.users.add(u);
}
public void deleteUser(User u){
this.users.remove(u);
}
//通知观察者
public void notifyUser(){
for (int i = 0;i<this.users.size();i++){
User user = users.get(i);
new Thread(user).start();
}
}
public Vector<Float> getSplitBox() {
return splitBox;
}
}
public class User implements Runnable {
private String name;
private static RedPacketSystem system = RedPacketSystem.getInstance();
public User(String name){
this.name = name;
}
public void sendRedRacket(float money,int num){
//Vector<Float> redpacket
RedPacketSystem system = RedPacketSystem.getInstance();
System.out.println(this.name+"发红包啦,发了"+money+"元,总共"+num+"个包");
system.splitMoney(money, num);
system.notifyUser();
}
/**
* 抢红包:snatchRedPacket
*/
public void snatchRedPacket(){
Vector<Float> redPacket = system.getSplitBox();
try {
Float money = redPacket.get(0);
redPacket.remove(0);
System.out.println(this.name + "抢到了" + money + "元");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("很遗憾,"+this.name+"没有抢到红包");
}
}
@Override
public void run() {
this.snatchRedPacket();
}
}
public class Test {
public static void main(String[] args) {
RedPacketSystem sys = RedPacketSystem.getInstance();
User user1 = new User("小明");
User user2 = new User("小红");
User user3 = new User("小张");
User user4 = new User("小李");
User user5 = new User("小五");
sys.addUser(user1);
sys.addUser(user2);
sys.addUser(user3);
sys.addUser(user4);
sys.addUser(user5);
//user1.sendRedRacket(80,4);
user2.sendRedRacket(10F,3);
}
}