原文地址: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);
}
}
}
優缺點
優點:
- 提高系統的可擴充性,在兩個變化維度中任意擴展一個維度,都不需修改原有系統。
- 將抽象化和實現化之間的耦合解脫開,將兩個角色之間的繼承關係改爲聚合關係,從而使兩者可以相對獨立地變化。
缺點:
- 要求正確識別出系統中兩個獨立變化的維度,所以其使用範圍具有一定的侷限性。