现实中的 JAVA (一)

发布时间 2023-06-22 22:53:38作者: ayiZzzz

买零食

描述

本例子主要是通过 JAVA 语言来描述,平时父母带我们去买零食的场景。

买零食流程图

  • 从家里出发,选择一种出行方式达到零食店然后我们就可以开始购物了,选择对应的零食随后进行买单

家庭成员 UML 图

1、Person 做为顶级的抽象类
2、Male 作为男 CLass 的描述类
3、Female 作为女 CLASS 的描述类

Person

@Data
public  abstract class Person {

    protected String name;


    protected int age;

    /**
     * 单位 cm
     */
    protected int height;

    /**
     * 单位 kg
     */
    protected int weight;

}

Male

@Data
public class Male extends Person{

    private String gender = GenderEnum.MALE.name();

    protected String education;

}

Female

@Data
public class Female extends Person{

    private String gender = GenderEnum.FEMALE.name();

    protected String education;
}

1、以上代码通过枚举类 GenderEnum 来对性别进行描述从而使代码的可读性更高


家庭描述实体类

Mother

@Data
@Accessors(chain =true)
public class Mother extends Female {

    private String identity = FamilyEnum.FATHER.name();

    private String profession;
}

Father

@Data
@Accessors(chain =true)
public class Father extends Male {

    private String identity = FamilyEnum.FATHER.name();

    private String profession;

}

Child

@Data
@Accessors(chain =true)
public class Child extends Person {

    private String identity = FamilyEnum.FATHER.name();

    private String profession;
}

  • @Accessors(chain =true) 注解作用是使类的属性可以进行链式调用

零食店 UML

Snack


@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain =true)
@ToString
public class Snack {

    /**
     * 零食名称
     */
    public String name;

    /**
     * 零售价
     */
    public double retailPrice;

    /**
     * 生产日期
     */
    public Date ProductionDate;

    /**
     * 出厂价
     */
    public double factoryPrice;


    // TODO 更多属性稍后补充

}

SnackWrapper

@Accessors(chain =true)
@NoArgsConstructor
@Data
public class SnackWrapper {

    int amount;

    Snack snack;

    public static SnackWrapper build(int amount , Snack snack) {
        SnackWrapper snackWrapper = new SnackWrapper();
        snackWrapper.setSnack(snack);
        snackWrapper.setAmount(amount);
        return snackWrapper;
    }
}

SnackShop

@Component
public class SnackShop implements InitializingBean {

    /**
     * 零食集合 - 存货 使用 List <Map> 结构
     * volatile 保证多线程环境下的可见性
     */
    public volatile Set<SnackWrapper> snackSet = Sets.newHashSet();

    private Faker faker = new Faker();


    public void setSnackSet(Set<SnackWrapper> snackSet) {
        this.snackSet = snackSet;

    }

    public void show() {
        snackSet.forEach(each -> {
            System.out.println("当前商品 :" + each.getAmount() + "---现有存货: " + each.getSnack().getName());
        });
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        List<Snack> snacks = new ArrayList<>(32);
        /**
         * 初始化零食
         */
        Faker faker = new Faker();
        Snack snack = new Snack();
        snack.setName("milt");
        snack.setFactoryPrice(5.00d);
        snack.setRetailPrice(8.00d);
        snack.setProductionDate(faker.date().birthday());

        snacks.add(snack);

        Snack snack2 = new Snack();
        snack2.setName("mackerel");
        snack2.setFactoryPrice(9.00d);
        snack2.setRetailPrice(15.00d);
        snack2.setProductionDate(faker.date().birthday());
        snacks.add(snack2);
        Snack snack3 = new Snack();
        snack3.setName("japaneseseabass");
        snack3.setFactoryPrice(20.00d);
        snack3.setRetailPrice(32.00d);
        snack3.setProductionDate(faker.date().birthday());
        snacks.add(snack3);

        /**
         * 构建 SnackWrapper
         */
        for (int i = 0 ; i < snacks.size() ; i ++ ) {
            SnackWrapper snackWrapper = SnackWrapper.build(5 , snacks.get(i));
            snackSet.add(snackWrapper);
        }
    }


    /**
     * 买单
     * @param snackWrappers 购物商品集合 - 数量
     * @return
     */
    public SpendWrapper payBill(List<SnackWrapper> snackWrappers) {
        /**
         * 什么都没买直接走人把
         */
        if (CollUtil.isEmpty(snackWrappers)) {
            return new SpendWrapper();
        }

        double spendMoney = calcSpendMoney(snackWrappers);

        /**
         * 减库存 - 这里可以采取异步的操作
         */
        cutStock(snackWrappers);

        return SpendWrapper.builder().
                spendMoney(spendMoney)
                .waiterName(faker.name().name())
                .billingTime(DateUtil.date(System.currentTimeMillis()))
                .build();
    }


    /**
     * 扣减库存
     */
    public void cutStock(List<SnackWrapper> snackWrappers) {

        /**
         * TODO 该实现需要完善
         */
        Iterator<SnackWrapper> iterator = snackSet.iterator();

        for (int i = 0 ; i < snackWrappers.size() ; i ++ ) {
           while (iterator.hasNext()) {
               SnackWrapper next = iterator.next();
               if (next.getSnack().getName().equals(snackWrappers.get(i).getSnack().getName())) {
                   Preconditions.checkArgument((next.getAmount() - snackWrappers.get(i).getAmount()) > 0 , "\n" +
                           "Inventory shortage");
                   next.setAmount(next.getAmount() - snackWrappers.get(i).getAmount());
               }
           }
        }
    }

    private double calcSpendMoney(List<SnackWrapper> snackWrappers) {
        double spendMoney = 0.00d;
        for (SnackWrapper snackWrapper : snackWrappers) {
            double price = snackWrapper.getAmount() * snackWrapper.getSnack().retailPrice;
            Preconditions.checkArgument(price > 0 , "calc snack price can not less than 0");
            spendMoney = spendMoney + price;
        }
        return spendMoney;
    }
}