天天看點

設計模式之橋接模式一 模式背景二 橋接模式三 代碼實作

一 模式背景

在很多時候,繼承足以解決很多問題了,但是有的還不是更優秀的解決方案。比如有時候可能會遇到那種組合式的類,有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報表工具類");

    }

}
           

繼續閱讀