今天来学习桥接模式,在我们日常生活中,有很多的事物是可以“多维度”的变化的,比如我们去吃面条,有鸡丝面和牛肉面两种,每一种面又分为辣味的和不辣的,而且每种面可能会分为大碗小碗的。。。很多事物能够变化的维度不止一种,甚至数十种,那么我们在代码上怎么应对这些变化呢?每一个都单独弄一个类显然不是什么好办法。。那么我们就需要用到今天学习的桥接模式了。
只知道概念是不够的,那么我们怎么去做呢?简单的来说, 桥接模式的做法是把变化部分抽象出来,使变化部分与主类分离开来,从而将多个维度的变化彻底分离。最后,提供一个管理类来组合不同维度上的变化,通过这种组合来满足业务的需要。
上边这句话是不是很拗口?其实我也看不懂,没关系,我们敲一遍就知道是什么意思了。
我们举个生活中的例子,就拿电脑的CPU来说,我们知道CPU生产厂商有两家比较出名,那就是AMD和Intel,他们旗下的产品有好多型号,为了简单起见,我们把这些型号按频率分为2GHz和3GHz两组。好了,现在两个维度已经出来了,一个是生产厂商,一个就是CPU的频率了。我们就用这个作为例子,来说明一下桥接模式的用法。
首先还是先贴出包结构:
我们首先把频率抽象为接口(生产厂商是接口也可以,这个无所谓的)
package com.bridge.intf;
/**
* CPU的频率
* @author ZHENGWEI
* @date 2015-8-7
*/
public interface CPURate {
/**
* 输出CPU的频率
*/
public void rate();
}
其次就是2GHz和3GHz的实现类
package com.bridge.impl;
import com.bridge.intf.CPURate;
/**
* 频率为2GHz的CPU
* @author ZHENGWEI
* @date 2015-8-7
*/
public class Rate2CPU implements CPURate {
/**
* 2GHz
*/
public void rate() {
System.out.println("我的频率是2GHz");
}
}
package com.bridge.impl;
import com.bridge.intf.CPURate;
/**
* 频率为3GHz的CPU
* @author ZHENGWEI
* @date 2015-8-7
*/
public class Rate3CPU implements CPURate {
/**
* 3GHz
*/
public void rate() {
System.out.println("我的频率是3GHz");
}
}
以上只是简单的输出,在正式项目中可以替换为具体的操作。
然后就是一个抽象类,我们这里把生产厂商作为抽象类(两个维度是可以变化的,一个抽象类一个接口,或者两个都是接口也可以,但是抽象类作为一个“管理者”,是一定要有的,也就是说两个维度都是接口的话,还要在新建一个抽象类,这里只不过把生产厂商的维度和抽象类结合在一起了)
package com.bridge.abs;
import com.bridge.intf.CPURate;
/**
* CPU的生产厂商
* @author ZHENGWEI
* @date 2015-8-7
*/
public abstract class CPUFactory {
protected CPURate CPURate;
public CPUFactory(CPURate CPURate){
this.CPURate = CPURate;
}
public abstract void AbsCPUFactory();
}
之后就是生产厂商的具体实现了
package com.bridge.abs.impl;
import com.bridge.abs.CPUFactory;
import com.bridge.intf.CPURate;
/**
* 具体的CPU生产厂商
* @author ZHENGWEI
* @date 2015-8-7
*/
public class AMD extends CPUFactory{
public AMD(CPURate CPURate) {
super(CPURate);
}
@Override
public void AbsCPUFactory() {
System.out.println("我是AMD生产的CPU");
this.CPURate.rate();
}
}
package com.bridge.abs.impl;
import com.bridge.abs.CPUFactory;
import com.bridge.intf.CPURate;
/**
* 具体的CPU生产厂商
* @author ZHENGWEI
* @date 2015-8-7
*/
public class Intel extends CPUFactory{
public Intel(CPURate CPURate) {
super(CPURate);
}
@Override
public void AbsCPUFactory() {
System.out.println("我是Intel生产的CPU");
this.CPURate.rate();
}
}
最后是测试类
package com.bridge.main;
import com.bridge.abs.impl.AMD;
import com.bridge.abs.impl.Intel;
import com.bridge.impl.Rate2CPU;
import com.bridge.impl.Rate3CPU;
public class BridgeMain {
public static void main(String[] args){
Rate2CPU rate2CPU = new Rate2CPU();
Rate3CPU rate3CPU = new Rate3CPU();
AMD amd1 = new AMD(rate2CPU);
amd1.AbsCPUFactory();
System.out.println("----------------------------");
Intel intel1 = new Intel(rate2CPU);
intel1.AbsCPUFactory();
System.out.println("----------------------------");
AMD amd2 = new AMD(rate3CPU);
amd2.AbsCPUFactory();
System.out.println("----------------------------");
Intel intel2 = new Intel(rate3CPU);
intel2.AbsCPUFactory();
System.out.println("----------------------------");
}
}
最后的结果
这样一来,我们分别实现了每一个维度,这些不同的维度之间就可以随意切换了,避免了每一个新的类型就要新建一个类。多个维度的也是如此。