← 返回首页
设计模式基础教程(十六)
发表时间:2021-08-23 08:40:34
桥接模式

1.桥接模式

桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。

设想如果要绘制矩形、圆形、椭圆、正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,此时至少有如下两种设计方案:

对于有两个变化维度(即两个变化的原因)的系统,采用方案二来进行设计系统中类的个数更少,且系统扩展更为方便。设计方案二即是桥接模式的应用。桥接模式将继承关系转换为关联关系,从而降低了类与类之间的耦合,减少了代码编写量。

桥接模式包含如下角色: - Abstraction:抽象类 - RefinedAbstraction:扩充抽象类 - Implementor:实现类接口 - ConcreteImplementor:具体实现类

2.实例

现需要提供大中小3种型号的画笔,能够绘制5种不同颜色,如果使用蜡笔,我们需要准备3*5=15支蜡笔,也就是说必须准备15个具体的蜡笔类。而如果使用毛笔的话,只需要3种型号的毛笔,外加5个颜料盒,用3+5=8个类就可以实现15支蜡笔的功能。本实例使用桥接模式来模拟毛笔的使用过程。

项目结构图如下:

定义颜色接口

public interface Color {
    void bepaint(String penType,String name);
}

定义不同颜色的实现类

//Black.java
public class Black implements Color {
    @Override
    public void bepaint(String penType, String name) {
        System.out.println(penType+"黑色的"+name+".");
    }
}

//Blue.java
public class Blue implements Color {
    @Override
    public void bepaint(String penType, String name) {
        System.out.println(penType+"蓝色的"+name+".");
    }
}

//Red.java
public class Red implements Color {
    @Override
    public void bepaint(String penType, String name) {
        System.out.println(penType+"红色的"+name+".");
    }
}

//White.java
public class White implements Color {
    @Override
    public void bepaint(String penType, String name) {
        System.out.println(penType+"白色的"+name+".");
    }
}

定义Pen抽象类

public abstract class Pen {

    protected Color color;
    protected String type;
    public Pen(String type){
        this.type = type;
    }
    public void setColor(Color color) {
        this.color = color;
    }
    public abstract void draw(String name);
}

定义大中小三种不同尺寸的笔

//BigPen.java
public class BigPen extends Pen {

    public BigPen(String type) {
        super(type);
    }
    @Override
    public void draw(String name) {
        String penType="大号"+this.type+"绘制";
        this.color.bepaint(penType, name);
    }
}

//MiddlePen.java
public class MiddlePen extends Pen {
    public MiddlePen(String type) {
        super(type);
    }
    @Override
    public void draw(String name) {
        String penType="中号"+this.type+"绘制";
        this.color.bepaint(penType, name);
    }
}

//SmallPen.java
public class SmallPen extends Pen {

    public SmallPen(String type) {
        super(type);
    }
    @Override
    public void draw(String name) {
        String penType="小号"+this.type+"绘制";
        this.color.bepaint(penType, name);
    }
}

XML解析工具类

public class XMLUtils {

    public static Object getBean(String args){
        DocumentBuilderFactory documentBuilderFactory=DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder documentBuilder= documentBuilderFactory.newDocumentBuilder();
            Document doc=documentBuilder.parse(XMLUtils.class .getClassLoader().getResourceAsStream("configPen.xml"));
            NodeList nodeList=doc.getElementsByTagName("className");
            String type=null;
            if("color".equals(args)){
                type=nodeList.item(0).getTextContent();
                return Class.forName(type).newInstance();
            }else if("pen".equals(args)){
                //type=nodeList.item(1).getTextContent();
                NodeList subNodeList = nodeList.item(1).getChildNodes();
                String className = subNodeList.item(1).getTextContent();
                System.out.println("className=" + className);
                String penType = subNodeList.item(3).getTextContent();
                return Class.forName(className).getDeclaredConstructor(String.class).newInstance(penType);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

配置文档

<?xml version="1.0"?>
<config>
    <className>com.simoniu.domain.Red</className>
    <className>
        <size>com.simoniu.domain.SmallPen</size>
        <type>蜡笔</type>
    </className>
</config>

测试类

public class TestBridgeDemo01 {
    public static void main(String[] args) {
        Color color=(Color) XMLUtils.getBean("color");
        Pen pen=(Pen) XMLUtils.getBean("pen");
        pen.setColor(color);
        pen.draw("鲜花");
    }
}

运行结果:
className=com.simoniu.domain.SmallPen
小号蜡笔绘制红色的鲜花.