内部类作用

2023-03-15  本文已影响0人  zxbyh

内部类的作用就是增加软件系统的内聚.

一 如果一个对象B只能作为对象A的成员,那么就应该吧这个B作为A的内部类.

下面举一个下订单场景的例子。业务诉求如下:
1,商品如果参加了活动就会根据用户的会员等级8折。
2,商家可以在订单总额上再折扣一定额度。
代码如下:

@RequiredArgsConstructor
@Getter
public class OrderInfo {
    private final String orderCode;
    private final String shopId;
    private final String buyerId;
    private final Integer buyerLevel;
    private Double discountAmount = 0D;
    private final Long orderDate;
    private List<OrderGoods> orderGoodsList = new ArrayList<>();

    @AllArgsConstructor
    @Data
    public class OrderGoods{
        private final String orderGoodsCode;
        private final String skuId;
        private Integer num;
        private final Double price;
        private final Boolean ifAct; //是否有活动

        private Double calculateAmount(){
            Double tmp = this.price*this.num;
            //例如 要根据用户的等级进行折扣;
            if(this.ifAct && buyerLevel>=2){ //内部类里面可以非常方便的访问宿主类
                tmp = tmp*0.8;
            }

            return tmp;
        }

    }

    //增加sku到订单中. 如果sku是已存在的,就增加数量并检查价格是否变动,否则就加进去.
    public OrderInfo addGoods(String orderGoodsCode, String skuId, Integer num, Double price, Boolean ifAct) {
        this.orderGoodsList.stream().filter(x->x.getSkuId().equals(skuId)).findFirst().ifPresentOrElse(
            x->{
                Asserts.defend(x.getPrice().doubleValue()!=price.doubleValue(),-1001,"sku价格变动!");
                x.setNum(num+x.getNum());
            },
            ()->this.orderGoodsList.add( new OrderGoods(orderGoodsCode, skuId, num, price, ifAct))
        );
        return this;
    }

    public Double calculateAmountFinal(){
        return this.orderGoodsList.parallelStream().mapToDouble(x->x.calculateAmount()).sum() - this.discountAmount; //内部类的私有方法可以在宿主类使用;
    }

}

弄成内部类的好处如下:
1 内部类里面可以非常方便的访问宿主类.
2 内部类的私有方法可以在宿主类使用.
3 内部类的构造函数应该在宿主类的方法里面执行.
4 如果要在外面new出这个内部类的话就要设置成public static , 但是如果出现这样的情形,就不适合弄成内部类了.

注意: 内部类要定义成public 才能在外面访问得到它的成员,

二 java 的函数不能返回多个参数 如果弄成Map<String,Object> 在使用的时候又不方便,这时候就可以弄一个内部类;
public class MoreReturn {
    private String info = "多返回值的演示说明!";

    public void deal(){
        //todo 其他的一些业务代码
        
        var rlt = this.getRlt();
        
        if(rlt.code==200){
            //todo 成功要干什么
        }
        else{
            //todo 失败要干什么
            
            Asserts.fail(rlt.code,rlt.Msg);
        }
    }
    
    
    @AllArgsConstructor
    @Data
    class TmpRtl {
        Integer code;
        String Msg;
    }
    TmpRtl getRlt(){
        return new TmpRtl(200,"Success");
    }
    
}
这时候更好的方式是使用record,来代替内部类 充当多返回参数的载体。
public class MoreReturn {
    private String info = "多返回值的演示说明!";

    public void deal(){
        //todo 其他的一些业务代码
        
        var rlt = this.getRlt();
        
        if(rlt.code==200){
            //todo 成功要干什么
        }
        else{
            //todo 失败要干什么
            Asserts.fail(rlt.code,rlt.msg);
        }
    }
    
    
    record TmpRlt(Integer code,String msg){}
    TmpRlt getRlt(){
        return new TmpRlt(200,"Success");
    }
    
}
三 更神奇的用法在函数里面定义内部类,record,enum 。
public static void main(String[] args) {
        enum GoodsField{ price, name, category }
        
        System.out.println(JSONUtil.toJsonPrettyStr(
            calculateParam(
                List.of(
                    new QRecord(GoodsField.name,Opt.like,"测试"),
                    new QRecord(GoodsField.price,Opt.greater_equal,129.9D),
                    new QRecord(GoodsField.price,Opt.less_equal,299.9D)
                )
            )
        ));
    }
上一篇 下一篇

猜你喜欢

热点阅读