設計模式入門:橋接模式

原文地址:http://te-amo.site/user/article/info/ARTICLE20180423081637711
文章中部分定義和解釋性文字,都是引用百度百科,主要的代碼及場景應用爲本人原創

橋接模式是將抽象部分與它的實現部分分離,使它們都可以獨立地變化

場景:在一個文件管理系統中,文件來源有兩個一個本地文件源,一個FTP文件源,而需要開發的客戶端因功能不同,有多中文件客戶端。客戶端和文件源都是可以變化的,而且文件源也會隨着系統複雜化,不斷增加,爲了保證客戶端和文件源的多變靈活性,可以使用橋接模式

結構

  • 抽象化角色:抽象化給出的定義,並保存一個對實現化對象的引用。(FileClient)
  • 修正抽象化角色:擴展抽象化角色,改變和修正父類對抽象化的定義。(SimpleFileClient,MultifunctionalFileClient)
  • 實現化角色:這個角色給出實現化角色的接口,但不給出具體的實現。(FileSource)
  • 具體實現化角色:這個角色給出實現化角色接口的具體實現。(FtpFileSource,LocalFileSource)

設計

這裏寫圖片描述

實現

代碼地址:https://github.com/telundusiji/designpattern

實現化角色 文件源接口

public interface FileSource {
    List<String> searchFile(String name);
    List<String> list();
    void delete(String name);
}

具體實現化角色 FTP文件源

@Slf4j
public class FtpFileSource implements FileSource {

    private List<String> files;

    public FtpFileSource() {
        files = new ArrayList<>();
        files.add("test1.txt");
        files.add("test2.txt");
        files.add("test4.txt");
        files.add("test17.txt");
        files.add("test3.txt");
        files.add("test15.txt");
        files.add("test8.txt");
        files.add("other.txt");
    }

    @Override
    public List<String> searchFile(String name) {
        log.info("登錄Ftp服務器...");
        log.info("開始搜索...");
        List<String> result = new ArrayList<>();
        for(String s : files){
            if(s.contains(name)){
                result.add(s);
            }
        }
        log.info("搜索完成!");
        return result;

    }

    @Override
    public List<String> list() {
        log.info("登錄Ftp服務器...");
        log.info("獲取所有文件完畢!");
        return files;
    }

    @Override
    public void delete(String name) {
        log.info("登錄Ftp服務器...");
        log.info("開始刪除文件...");
        Iterator<String> iterator = files.iterator();
        while (iterator.hasNext()){
            if(iterator.next().equals(name)){
                iterator.remove();
            }
        }
        log.info("刪除完成");
    }


}

具體實現化角色 本地文件源

@Slf4j
public class LocalFileSource implements FileSource {

    private List<String> files;

    public LocalFileSource() {
        files = new ArrayList<>();
        files.add("test7.txt");
        files.add("test10.txt");
        files.add("test56.txt");
        files.add("test17.txt");
        files.add("test9.txt");
        files.add("test0.txt");
        files.add("test8.txt");
        files.add("other.txt");
    }

    @Override
    public List<String> searchFile(String name) {
        log.info("開始搜索...");
        List<String> result = new ArrayList<>();
        for(String s : files){
            if(s.contains(name)){
                result.add(s);
            }
        }
        log.info("搜索完成!");
        return result;
    }

    @Override
    public List<String> list() {
        return files;
    }

    @Override
    public void delete(String name) {
        log.info("開始刪除文件...");
        Iterator<String> iterator = files.iterator();
        while (iterator.hasNext()){
            if(iterator.next().equals(name)){
                iterator.remove();
            }
        }
        log.info("刪除完成");
    }
}

抽象化角色 文件客戶端

@Data
public abstract class FileClient {

    private FileSource fileSource;

    public FileClient(FileSource fileSource) {
        this.fileSource = fileSource;
    }

    public abstract void list();

    public abstract void search(String name);

    public abstract void delete(String name);
}

修正抽象化角色 簡單文件客戶端

@Slf4j
public class SimpleFileClient extends FileClient {

    public SimpleFileClient(FileSource fileSource) {
        super(fileSource);
    }

    @Override
    public void list() {
        List<String> list = getFileSource().list();
        for(String s: list){
            log.info("文件:{}",s);
        }
    }

    @Override
    public void search(String name) {
        List<String> list = getFileSource().searchFile(name);
        log.info("---------------搜索{}結果--------------",name);
        for(String s: list){
            log.info("文件:{}",s);
        }
    }

    @Override
    public void delete(String name) {
        getFileSource().delete(name);
        log.info("--------------{}文件刪除-----------",name);
    }
}

修正抽象化角色 多功能文件客戶端

@Slf4j
public class MultifunctionalFileClient extends FileClient {

    public MultifunctionalFileClient(FileSource fileSource) {
        super(fileSource);
    }

    @Override
    public void list() {
        List<String> list = getFileSource().list();
        for(String s: list){
            log.info("文件:{}",s);
        }
    }

    public void listWithSort(){
        List<String> list = getFileSource().list();
        Collections.sort(list,String::compareTo);
        for(String s: list){
            log.info("文件:{}",s);
        }
    }

    @Override
    public void search(String name) {
        List<String> list = getFileSource().searchFile(name);
        log.info("---------------搜索{}結果--------------",name);
        for(String s: list){
            log.info("文件:{}",s);
        }
    }

    @Override
    public void delete(String name) {
        getFileSource().delete(name);
        log.info("--------------{}文件刪除-----------",name);
    }

    public void delete(String... args){
        for (String s : args){
            getFileSource().delete(s);
            log.info("--------------{}文件刪除-----------",s);
        }
    }
}

優缺點

優點:

  • 提高系統的可擴充性,在兩個變化維度中任意擴展一個維度,都不需修改原有系統。
  • 將抽象化和實現化之間的耦合解脫開,將兩個角色之間的繼承關係改爲聚合關係,從而使兩者可以相對獨立地變化。

缺點:

  • 要求正確識別出系統中兩個獨立變化的維度,所以其使用範圍具有一定的侷限性。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章