案例:公司经营,张三经营着两个公司,一个是房地产公司,一个是服装制造公司。
类图:
代码:
public abstract class Corp {
protected abstract void product();
protected abstract void sell();
/**
* 赚钱方法:先生产,再销售
*/
public void makeMoney() {
this.product();
this.sell();
}
}
public class HouseCorp extends Corp {
@Override
protected void product() {
System.out.println("承建XXX小区...");
}
@Override
protected void sell() {
System.out.println("卖房...");
}
@Override
public void makeMoney() {
super.makeMoney();
System.out.println("房地产公司盈利两千万...");
}
}
public class ClothCorp extends Corp {
@Override
protected void product() {
System.out.println("潮牌服装制造...");
}
@Override
protected void sell() {
System.out.println("出售潮牌服装...");
}
@Override
public void makeMoney() {
super.makeMoney();
System.out.println("服装公司盈利一百万...");
}
}
public class Client {
public static void main(String[] args) {
HouseCorp houseCorp = new HouseCorp();
houseCorp.makeMoney();
ClothCorp clothCorp = new ClothCorp();
clothCorp.makeMoney();
}
}
张三感觉服装公司盈利太少,于是把服装公司转型为制造iPad的公司,修改类图:
修改代码:
public class IPadCorp extends Corp {
@Override
protected void product() {
System.out.println("生产iPad...");
}
@Override
protected void sell() {
System.out.println("销售iPad...");
}
@Override
public void makeMoney() {
super.makeMoney();
System.out.println("iPad公司盈利一千万...");
}
}
public class Client {
public static void main(String[] args) {
HouseCorp houseCorp = new HouseCorp();
houseCorp.makeMoney();
// ClothCorp clothCorp = new ClothCorp();
// clothCorp.makeMoney();
IPadCorp iPadCorp = new IPadCorp();
iPadCorp.makeMoney();
}
}
这样确实实现了张三的需求,但存在的问题是:原来的服装公司彻底失去了制造和销售服装的功能,即没有保留原有的功能,如果以后再对iPad公司进行改造,让其制造和销售电脑,那么制造iPad的功能也会彻底丢失,张三感觉这样做成本太大了。
由此,我们引入桥梁模式。新的类图如下:
代码:
public abstract class Product {
public abstract void beProducted();
public abstract void beSelled();
}
public class House extends Product {
@Override
public void beProducted() {
System.out.println("承建XXX小区...");
}
@Override
public void beSelled() {
System.out.println("销售楼房...");
}
}
public class Cloth extends Product {
@Override
public void beProducted() {
System.out.println("潮牌服装制造...");
}
@Override
public void beSelled() {
System.out.println("出售潮牌服装...");
}
}
public class IPad extends Product {
@Override
public void beProducted() {
System.out.println("生产iPad...");
}
@Override
public void beSelled() {
System.out.println("销售iPad...");
}
}
public abstract class Corp {
// 定义一个产品对象
private Product product;
// 构造函数,由子类定义传递具体的产品进来
public Corp(Product product) {
this.product = product;
}
public void makeMoney() {
this.product.beProducted();
this.product.beSelled();
}
}
public class HouseCorp extends Corp {
public HouseCorp(Product product) {
super(product);
}
@Override
public void makeMoney() {
super.makeMoney();
System.out.println("房地产公司盈利两千万...");
}
}
public class MakeCrop extends Corp {
// 具体制造什么产品还不知道,调用的时候才知道
public MakeCrop(Product product) {
super(product);
}
@Override
public void makeMoney() {
super.makeMoney();
System.out.println("制造公司盈利五百万...");
}
}
public class Client {
public static void main(String[] args) {
House house = new House();
HouseCorp houseCorp = new HouseCorp(house);
houseCorp.makeMoney();
Cloth cloth = new Cloth();
IPad iPad = new IPad();
MakeCrop makeCrop = new MakeCrop(cloth);
makeCrop.makeMoney();
makeCrop = new MakeCrop(iPad);
makeCrop.makeMoney();
}
}
在代码中,HouseCorp类和MakeCorp类的区别是在有参构造器的参数类型上,HouseCorp类很明确自身职能,就是生产和制造House,所以直接传入House的对象,MakeCorp由于不确定具体制造和销售什么产品,所以传入的参数为Product抽象类类型。
这就是桥梁模式。总结:
- 桥梁模式具有很好的扩展性,如果要增加公司,可以直接继承Corp类或者HouseCorp类和MakeCrop类;如果要增加产品,直接继承Product类或者继承已有的产品实现类(比如要把房子再分为商用房、居住房等类型)
- 桥梁模式降低了类之间的耦合性
桥梁模式的通用类图如下:
- Abstraction:业务抽象角色,案例中的Corp、HouseCorp和MakeCrop
- Implementor:业务实现角色,案例中的Product、House、Cloth、IPad
- 业务抽象角色引用业务实现角色,或者说,业务抽象角色的部分实现是由业务实现角色完成的
本文原书《您的设计模式》作者:CBF4LIFE