桥接模式的最大特征就在区分成“功能的类层次”和“实现的类层次”。如果想新增功能的话,就在功能的类层次追加类。这时候不需要修改实现的类层次,新增加的功能利用接口定义的实现功能来组合实现。
如上图:左边部分是功能层次类,右边部分是实现层次类。它们通过变量impl来实现桥接。
对于添加不同的功能,如类似CountDisplay的功能,只需要添加**Display功能类。个人认为这里功能的添加是在Display类中方法不变就能提供足够功能的情况下完成的。否则就需要修改Display,响应的也需要在DiplayImpl里对功能进行扩充。
//Display类
public class Display
{
private DisplayImpl impl;
public Display(DisplayImpl impl)
{
this.impl = impl;
}
public void open()
{
impl.rawOpen();
}
public void print()
{
impl.rawPrint();
}
public void close()
{
impl.rawClose();
}
public final void display()
{
open();
print();
display();
}
}
//DisplayImpl类
public abstract class DisplayImpl
{
public abstract void rawOpen();
public abstract void rawPrint();
public abstract void rawClose();
}
//CountDisplay类
public class CountDisplay extends Display
{
public CountDisplay(DisplayImpl impl)
{
super(impl);
}
public void multiDisplay(int times)
{
open();
for(int i = 0;i<times;i++)
{
print();
}
close();
}
}
//StringDisplay类
public class StringDisplayImpl extends DisplayImpl
{
private String string;
private int width;
public StringDisplayImpl(String string)
{
this.string = string;
this.width = string.getBytes().length;
}
public void rawOpen()
{
printLine();
}
private void printLine()
{
System.out.println("+");
for(int i = 0;i<2;i++)
{
System.out.println("-");
}
System.out.println("+");
}
@Override
public void rawPrint()
{
System.out.println("|"+string+"|");
}
@Override
public void rawClose()
{
printLine();
}
}
//Bridge测试类
public class Bridge
{
/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
// TODO code application logic here
Display d1 = new Display(new StringDisplayImpl("hello world"));
CountDisplay d2 = new CountDisplay(new StringDisplayImpl("hello daniel"));
d1.display();
d2.multiDisplay(3);
}
}
通常,扩充类时可以通过继承来实现,不过继承让子类和父类的关系牢不可分。如果根据需要修改类之间的关系,继承就不可行了。
桥接模式通过变量impl这种方式来把任务“委托”给实现类(接口),这样就变得灵活可操控。