【设计模式】通过点一杯奶茶,我学会了·桥接模式·的奥妙

191 阅读2分钟

点奶茶需要指定其类型,同类型的奶茶又分大中小杯.

于是我希望可以用如下代码所呈现的方式,先指定类型GreenTea,再指定尺寸Large后,将一杯奶茶Tea做出new)来

Tea greenTea = new GreenTea(new Large());
Tea redTea = new RedTea(new Middle());

由于尺寸有大中小三种类型,我们创建Size接口

public interface Size {
}

由于茶有各种各样的茶,我们创建Tea抽象类(因为需要有构造器,所以不用接口的形式)

public abstract class Tea {
    protected Size size;

    protected Tea(Size size) {
        this.size = size;
    }
}

实现接口和抽象类

public class Large implements Size {
}
public class Middle implements Size {
}
public class Large implements Size {
}
public class RedTea extends Tea{
    protected RedTea(Size size) {
        super(size);
    }
}
public class GreenTea extends Tea{
    protected GreenTea(Size size) {
        super(size);
    }
}

于是乎,我们就可以成功根据客户的需求,做出一杯奶茶来啦.

但是我们还得知道做出来的奶茶的价格是多少,所以还需要在其中添加方法

需求是这样的,每类茶都有一个基础价格,茶根据尺寸让基础价格乘以一个系数得到最终的价格.

小杯的系数是1.0,中杯的系数是1.5,大杯的系数是2

例如: 柠檬果茶的基础价格是4元,那么小杯就是4元,中杯是6元,大杯是8元.

于是,添加抽象方法 基础价格basePrice, 系数ratio

public abstract class Tea {
    protected Size size;

    protected Tea(Size size) {
        this.size = size;
    }

    public abstract BigDecimal basePrice();
}
public interface Size {
    BigDecimal ratio();
}

实现,设定基础价格和系数

public class GreenTea extends Tea{
    protected GreenTea(Size size) {
        super(size);
    }

    @Override
    public BigDecimal basePrice() {
        return new BigDecimal(15);
    }
}
public class RedTea extends Tea{
    protected RedTea(Size size) {
        super(size);
    }

    public BigDecimal basePrice(){
        return new BigDecimal(10);
    }

}
public class Large implements Size {
    @Override
    public BigDecimal ratio() {
        return new BigDecimal(2);
    }
}
public class Middle implements Size{
    @Override
    public BigDecimal ratio() {
        return new BigDecimal(1.5);
    }
}
public class Small implements Size{
    @Override
    public BigDecimal ratio() {
        return new BigDecimal(1);
    }
}

最后添加不需要被重写的普通方法

public abstract class Tea {
    protected Size size;

    protected Tea(Size size) {
        this.size = size;
    }

    public abstract BigDecimal basePrice();

    public BigDecimal ratio() {
        return size.ratio();
    }

    public BigDecimal finalPrice() {
        return size.ratio().multiply(basePrice());
    }

    @Override
    public String toString() {
        return "Tea{" +
                "ratio=" + ratio().toString() + "," +
                "basePrice=" + basePrice().toString() + "," +
                "finalPrice=" + finalPrice().toString() +
                '}';
    }
}

好嘞,大功告成,一杯奶茶新鲜出炉

Tea greenTea = new GreenTea(new Large());
System.out.println("greenTea = " + greenTea);
Tea redTea = new RedTea(new Middle());
System.out.println("redTea = " + redTea);
/*
 * greenTea = Tea{ratio=2,basePrice=15,finalPrice=30}
 * redTea = Tea{ratio=1.5,basePrice=10,finalPrice=15.0}
 */

System.out.println("先生,你需要付款" + greenTea.finalPrice().add(redTea.finalPrice()) + "元");
/*
 * 先生,你需要付款45.0元
 */