天天看点

设计模式之桥接模式一 模式背景二 桥接模式三 代码实现

一 模式背景

在很多时候,继承足以解决很多问题了,但是有的还不是更优秀的解决方案。比如有时候可能会遇到那种组合式的类,有2个维度可以变化,进行不同的组合,然后完成不同的功能。比如开发报表功能的时候,可选则的报表工具是一个维度,要构建什么类型的报表又是一个维度,我们可以通过不同的报表工具完成这些报表的产生。如图示:

设计模式之桥接模式一 模式背景二 桥接模式三 代码实现

如果我们定一个抽象基类ReportTools, 然后要实现以XML,CVS格式输出形成报表,我们使用JasperReport,则需要创建2个类:

JasperXMLReportTools 和 JasperCVSReportTools,代码如下:

public abstract class ReportTools {
    public abstract String build();
    public void writeTo(String path) throws IOException {
        File file = new File(path);
        String content = build();
        FileUtils.write(file,content, Charset.defaultCharset());
    }
}



public class JasperXMLReportTools extends ReportTools {



    public String build() {

        return "[Jasper]XML 内容";

    }



    @Override

    public void writeTo(String path) throws IOException {

        System.out.println("[Jasper]将内容以XML它输出到文件: "+path);

        super.writeTo(path);

    }

}


public class JasperCVSReportTools extends ReportTools {



    public String build() {

        return "[Jasper]CVS 内容";

    }



    @Override

    public void writeTo(String path) throws IOException {

        System.out.println("[Jasper]将内容以CVS它输出到: "+path);

        super.writeTo(path);

    }

}
           

如果此时,要新增报表工具JFreerReport,那么我们就必须要同时提供XML和CVS的实现,JFreeReportCVSReportTools和JFreeReportXMLReportTools。代码如下:

public class JFreeReportCVSReportTools extends ReportTools{



    public String build() {

        return "[JFreeReport]CVS 内容";

    }



    @Override

    public void writeTo(String path) throws IOException {

        System.out.println("[JFreeReport]将内容以CVS它输出到文件: "+path);

        super.writeTo(path);

    }

}


public class JFreeReportXMLReportTools extends ReportTools {



    public String build() {

        return "[JFreeReport]XML 内容";

    }



    @Override

    public void writeTo(String path) throws IOException {

        System.out.println("[JFreeReport]将内容以XML它输出到文件: "+path);

        super.writeTo(path);

    }

}
           

那么如果又有新需求,我们要新增新报表工具类OpenReport,那么此时是不是又要增加两个类,或者我们需要新增其他的格式的报表,比如PDF或者HTML,那么类的个数又要翻倍。

我们可以看到其实build只是构建不同格式的内容,而writeTo只是将构建的这些内容写入磁盘。所以相对于来说变化的就是build这个方法。那既然这样,那么针对有2个维度变化的需求,我们可以使用桥接模式,将他的抽象部分(build)与实现部分开,是抽象和实现可以独立的变化。z

二 桥接模式

2.1 什么是桥接,什么是桥接模式

桥接:原本不相通的东西通过桥连接起来。

桥接模式:将抽象和实现进行分离解耦,使得抽象和实现可以独自变化

设计模式之桥接模式一 模式背景二 桥接模式三 代码实现

2.2 为何需要桥接 以及 如何桥接

为了达到抽象和实现部分都可独立变化,所以抽象部分和实现部分开的,但是分来比意味着抽象部分不使用实现部分功能,那如何使用呢,很明显搭个桥就可以。

那如何桥接呢?我么只需要在抽象部分引入实现接口,然后就可以通过该接口调用实现部分具体的功能了。

三 代码实现

public interface Report {

    abstract String build();

}


public class CVSReport implements Report {

    public String build() {

        return "CVS 内容";

    }

}


public class XMLReport implements Report {

    public String build() {

        return "XML内容";

    }

}


public abstract class ReportTools {



    private Report report;



    public ReportTools(Report report) {

        this.report = report;

    }



    public void writeTo(String path) throws IOException {

        File file = new File(path);

        String content = this.report.build();

        FileUtils.write(file,content, Charset.defaultCharset());

    }



    public void desc(){

        System.out.println("报表工具类基类");

    }

}


public class JasperReportTools extends ReportTools {



    public JasperReportTools(Report report) {

        super(report);

    }



    @Override

    public void desc() {

        System.out.println("Jasper报表工具类");

    }

}


public class JFreeReportTools extends ReportTools {

    public JFreeReportTools(Report report) {

        super(report);

    }



    @Override

    public void desc() {

        System.out.println("JFreeReport报表工具类");

    }

}
           

继续阅读