我理解的就是零件的装配,用在需要把一些有联系的属性拼接起来。
如StringBuilder就是很典型的。
引入一个场景,去药房抓中药,有以下组成:
1、药品 (抽象零件)
2、天麻、枸积、何首乌(具体零件)
3、Builder组装接口 (抽象组装)
4、Builder 组装实现类
// 抽象零件
public interface Medicine {
String getName();
double getPrise();
String getDesc();
}
// 具体零件
public class GouJi implements Medicine {
@Override
public String getName() {
return "枸积";
}
@Override
public double getPrise() {
return 20;
}
@Override
public String getDesc() {
return "宁夏五宝之首";
}
}
public class HeShouWu implements Medicine {
@Override
public String getName() {
return "何首乌";
}
@Override
public double getPrise() {
return 35;
}
@Override
public String getDesc() {
return "黑头发的何首乌";
}
}
public class TianMa implements Medicine {
@Override
public String getName() {
return "天麻";
}
@Override
public double getPrise() {
return 124;
}
@Override
public String getDesc() {
return "治头痛的天麻";
}
}
// 抽象组装接口
public interface MedicineOps {
MedicineOps addGouji();
MedicineOps addHeShouWu();
MedicineOps addTianMa();
String getDetails();
}
// 具体组装类
public class Diagnosis implements MedicineOps{
private List<Medicine> medicines = new ArrayList<>();
private Double price;
private String yisheng;
private String bingQing;
public Diagnosis(String bing, String yisheng){
this.bingQing = bing;
this.yisheng = yisheng;
price = 0d;
}
@Override
public MedicineOps addGouji() {
GouJi gouJi = new GouJi();
medicines.add(gouJi);
this.price += gouJi.getPrise();
return this;
}
@Override
public MedicineOps addHeShouWu() {
HeShouWu heShouWu = new HeShouWu();
medicines.add(heShouWu);
this.price += heShouWu.getPrise();
return this;
}
@Override
public MedicineOps addTianMa() {
TianMa tianMa = new TianMa();
medicines.add(tianMa);
this.price += tianMa.getPrise();
return this;
}
@Override
public String getDetails() {
StringBuilder sb = new StringBuilder();
sb.append("主治医师:").append(yisheng).append("\n病情:").append(bingQing).append("\n所用中药有:\n");
for (Medicine medicine : medicines) {
sb.append(medicine.getName()).append(" : ").append(medicine.getDesc()).append("\n");
}
sb.append("总共价格为:").append(price);
return sb.toString();
}
}
// 调用
public class Builder {
public MedicineOps getA() {
return new Diagnosis("脑壳痛", "刘德光大夫").addGouji().addHeShouWu().addTianMa();
}
public static void main(String[] args) {
System.out.println(new Builder().getA().getDetails());
}
}
// 结果
/*
主治医师:刘德光大夫
病情:脑壳痛
所用中药有:
枸积 : 宁夏五宝之首
何首乌 : 黑头发的何首乌
天麻 : 治头痛的天麻
总共价格为:179.0
*/
可以看到调用的时候类似于StingBuilder,需要啥零件,就调用啥方法,以此组成不同的套餐。
使用场景:
基本物料不会变,但是其组合经常改变的时候。
比如咱有两个杯子:大杯子和小杯子,有三种饮料:可乐、橙汁、白开水。如果现在的场景是我要用杯子去喝饮料,那他们的组合会有2*3种,代表着咱得ifelseifelse.....
而桥接模式就可以让咱的这种尴尬代码得救
杯子和饮料都是单独变化的两个维度,并且不会互相影响,那咱就给它分别抽出来处理。
代码具有以下组成部分:
1、抽象类BeiZi,里面有一个饮料对象。
2、杯子的实现类
3、饮料接口
4、饮料实现类
在new 杯子的时候,将需要的饮料对象注入,达成匹配效果。
// 杯子抽象类
public abstract class BeiZi {
Beverages beverages;
public BeiZi(Beverages beverages) {
this.beverages = beverages;
}
public abstract void drick();
}
// 杯子实现类
public class BigBeiZi extends BeiZi {
public BigBeiZi(Beverages beverages){
super(beverages);
}
@Override
public void drick() {
System.out.println("我用大杯子喝"+beverages.witchBev());
}
}
public class SmallBeiZi extends BeiZi {
public SmallBeiZi(Beverages beverages) {
super(beverages);
}
@Override
public void drick() {
System.out.println("我正在用超可爱的小杯子喝"+beverages.witchBev());
}
}
//饮料接口
public interface Beverages {
String witchBev();
}
//饮料实现类
public class Cha implements Beverages {
@Override
public String witchBev() {
return "茶";
}
}
public class Colo implements Beverages{
@Override
public String witchBev() {
return "可乐";
}
}
// 测试
public class TestQIaoJie {
public static void main(String[] args) {
BigBeiZi bigBeiZi = new BigBeiZi(new Colo());
bigBeiZi.drick();
BigBeiZi bigBeiZi1 = new BigBeiZi(new Cha());
bigBeiZi1.drick();
SmallBeiZi smallBeiZi = new SmallBeiZi(new Colo());
smallBeiZi.drick();
}
}
// 结果
我用大杯子喝可乐
我用大杯子喝茶
我正在用超可爱的小杯子喝可乐
桥接模式的精髓就在于,分离出来的两个维度可以自由扩展哦!
如果按之前的ifelse来写,那么万一增加了一种饮料,那咱就得去业务代码种增加一个else了,违背了开闭原则。
因篇幅问题不能全部显示,请点此查看更多更全内容