设计模式之桥梁模式

时间:2021-12-15 16:00:39

桥梁模式也叫桥接模式,是指将抽象和实现解耦,使得两者可以独立地变化。桥梁模式的重点是在“解耦”上,来看下下面举的例子,看看重构前和用桥梁模式重构后的区别。

假如我有两家公司,一家做房地产,一家做山寨IPOD,两家都在帮我赚钱。

重构前:

设计模式之桥梁模式

public abstract class Company {
protected void makeMoney() {
this.produce();
this.sell();
}
//制造产品
public abstract void produce();
//销售产品
public abstract void sell();
}
public class HouseCompany extends Company {@Overridepublic void produce() {System.out.println("房地产开始建造房子");}@Overridepublic void sell() {System.out.println("房地产公司售卖房子");}public void makeMoney(){super.makeMoney();System.out.println("房地产赚大钱了");}}
public class IpodCompany extends Company {@Overridepublic void produce() {System.out.println("IPOD山寨公司开始制造");}@Overridepublic void sell() {System.out.println("山寨公司开始售卖IPOD");}public void makeMoney(){super.makeMoney();System.out.println("山寨公司赚钱了");}}
public class Client {public static void main(String[] args) {//房地产公司Company houseCompany = new HouseCompany();houseCompany.makeMoney();//IPOD山寨公司Company ipodCompany = new IpodCompany();ipodCompany.makeMoney();}}

这里有一个问题,就是突然有一天山寨公司不想做IPOD了,想做平板电脑了,那么produce和sell的方法就都得变更,这样子成本太大,也违反了DIP原则,这样就相当于把公司和产品强耦合在一起了。下面用桥梁模式重构一下这个功能。

重构后:

设计模式之桥梁模式

代码:

public abstract class Company {

private Product product;
public Company(Product _product){
this.product = _product;
}
public void makeMoney(){
this.produce();
this.sell();
};
public void produce(){
this.product.produce();
}
public void sell(){
this.product.sell();
}
}
public interface Product {public void produce();public void sell();}
public class HouseCompany extends Company{public HouseCompany(Product _product) {super(_product);}public void makeMoney(){super.makeMoney();System.out.println("房地产公司赚大钱了");}}
public class ShanZhaiCompany extends Company{public ShanZhaiCompany(Product _product) {super(_product);// TODO Auto-generated constructor stub}public void makeMoney(){super.makeMoney();System.out.println("山寨公司赚钱了");}}
public class HouseProd implements Product {@Overridepublic void produce() {System.out.println("开始建造房子");}@Overridepublic void sell() {System.out.println("开始销售房子");}}
public class IpodProd implements Product {@Overridepublic void produce() {System.out.println("生产IPOD产品");}@Overridepublic void sell() {System.out.println("开始销售IPOD产品");}}

经过重构之后,如果突然想让山寨公司转型做平板电脑,那么只需再从product派生一个平板产品类,传给山寨公司即可。这样就很好地将公司和产品解耦开来,这也正是桥梁模式的关键所在。在这个例子中,可以将公司理解为定义中的抽象,把产品理解为抽象实现,这样就能比较好理解桥梁模式的概念了。


使用场景:

- 不希望或不适用使用继承的场景,例如继承层次过度、无法更细化设计颗粒等场景,需要考虑使用桥梁模式。

- 接口或抽象类不稳定的场景。

- 重用性要求较高的场景,设计的颗粒度越细,则被重用的可能性就越大,而采用继承则受父类的限制,不可能出现太细的颗粒度。


对于继承来说,继承的有点很多,可以把公共的方法或属性抽取,父类封装共性,子类实现特性,这是继承的基本功能。但缺点就是强侵入性,父类有一个方法,子类也必须有这个方法,这是不可选择的,会带来扩展性问题。举个例子,Father类有个方法A,Son继承了这个方法,然后GradeSon也继承了这个方法,问题是突然有一天Son要重写父类的这个方法,但GradeSon又需要用到Father的这个方法,这时就带来了扩展的问题了。

对于上面的问题,桥梁模式就是这种问题的解决方法,它描述了一种弱关联关系,还是上面的例子,Father类完全可以把有可能发生变化的方法放出去,Son子类要拥有这个方法很简单,桥梁搭过去,获得这个方法,GrandSon也一样,即使Son子类不想使用这个方法了也没关系,对GrandSon不产生影响,它不是从Son中继承来的方法。