1. 程式人生 > >設計模式的藝術 結構性模式之橋接模式

設計模式的藝術 結構性模式之橋接模式

不懂使用為學過,說出用途,繪製結構為了解,不會靈活使用基本等於沒學。

前言

瞭解過畫畫的人都知道,顏色有很多種,紙也有很多種,但是他們直接怎麼連線起來呢??通過筆,來使其靈活生動的轉換起來,橋接模式也是這個原理,是一種物件結構型模式

什麼是橋接模式  Bridge Pattern

將抽象部分與其實現部分分離,使他們都可以獨立的變化,它是一種物件結構型模式,又被稱為柄體模式或者介面模式

橋接模式的優點

(1)、分離了抽象介面及其實現部分。橋接模式使用"物件間的關聯關係"解耦了抽象和實現之間固有的繫結關係,使得抽象和實現可以沿著各自的維度來變化(既抽象和實現不在同一個繼承層次結構中,而是"子類化"它們,使他們各自都有自己的子類,以便任意組合子類,從而獲得多維度組合物件)。

(2)、很多情況之下,橋接模式是可以取代多層繼承方案。多層繼承方案違背了單一職責原則,複用性比較差,且類的個數非常的多,橋接模式是比多層繼承方案更好的解決辦法,它極大的減少了子類的個數

(3)、橋接模式提高了系統的可擴充套件性,在兩個變化維度中任意擴充套件一個維度,都不需要修改原有程式碼,符合開閉原則

橋接模式的缺點

(1)、橋接模式的使用會增加系統的理解和設計難度,由於關聯關係建立在抽象層,要求開發者一開始就針對抽象層進行設計和程式設計

(2)、橋接模式要求能夠正確的識別出系統中兩個獨立變化的維度,因此其使用範圍具有一定的侷限性,如何正確識別兩個獨立維度也需要一定的經驗的積累。

橋接模式的使用場景

(1)、如果一個系統需要在抽象類和具體類之間增加更多的靈活性,避免在兩個層次之間建立靜態的繼承關係,通過橋接模式可以使他們在抽象層建立一個關聯關係

(2)、抽象部分和實現部分可以繼承的方式獨立擴充套件而互不影響,在程式執行時可以動態的將一個抽象類子類的物件和一個實現類子類的物件進行組合,即系統需要對抽象角色和實現類角色進行動態耦合

(3)、一個類存在兩個或者多個獨立的變化的維度,且這兩個或者多個維度都需要獨立進行擴充套件

(4)、對於那些不希望使用繼承或者因為多層繼承導致系統類的個數急劇增加的系統,橋接模式尤為適用

橋接模式的具體實現

在不同的系統中建立不同格式的圖片

目錄結構

抽象影象類以及具體實現類

package com.company;

public class Matrix {
    
}
package com.company.image;

import com.company.system.ImageImp;

//抽象影象類:抽象類,這是最重要的橋,將img介面放入其中,組合在一起,實現建立不同格式的圖片
 public abstract class Images {
     protected ImageImp imp;

    public void setImp(ImageImp imp) {
        this.imp = imp;
    }
    public abstract void parseFile(String fileName);
}
package com.company.image;


import com.company.Matrix;

public class JPGImage extends Images {
    @Override
    public void parseFile(String fileName) {
        //模擬解析JPG檔案並獲取一個畫素矩陣物件M;
        Matrix m=new Matrix();
         imp.doPaint(m);
        System.out.println(fileName+"格式為JPG");
    }
}
package com.company.image;

import com.company.Matrix;

public class PNGImage extends Images{
    @Override
    public void parseFile(String fileName) {
        //解析模擬PNG檔案並獲得一個畫素矩陣物件M
        Matrix m=new Matrix();
        imp.doPaint(m);
        System.out.println(fileName+"格式為PNG");
    }
}

抽象作業系統類以及實現類

package com.company.system;

import com.company.Matrix;

//抽象作業系統實現:實現類介面
public interface ImageImp {
        public void doPaint(Matrix matrix);  //顯示畫素矩陣matrix
}
package com.company.system;

import com.company.Matrix;

//Linux作業系統實現類:具體實現類
public class LinuxImp implements ImageImp {
    @Override
    public void doPaint(Matrix matrix) {
        //呼叫Linux系統的繪製函式畫素矩陣
        System.out.println("在UNIX作業系統中顯示影象");
    }
}
package com.company.system;

import com.company.Matrix;

//UXIX作業系統實現類:具體實現類
public class UnixImp implements ImageImp {
    @Override
    public void doPaint(Matrix matrix) {
            //呼叫UNIX系統的繪製函式繪製畫素矩陣
        System.out.println("在UNIX作業系統中顯示影象");
    }
}
package com.company.system;

import com.company.Matrix;

//Windows作業系統實現類:具體實現類
public class WindowsImp implements ImageImp {
    @Override
    public void doPaint(Matrix matrix) {
        //呼叫Windows系統的繪製函式繪製畫素矩陣
        System.out.println("在Windows作業系統中顯示影象");
    }
}

工具類

package com.company.util;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;

public class XMLUtil {
    public static Object getBean(String args) {
        try {
            //獲取文件物件
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuiler = documentBuilderFactory.newDocumentBuilder();
            Document document = documentBuiler.parse(new File(XMLUtil.class.getClassLoader().getResource("")
                    .getPath() + "config.xml"));
            //獲取節點的value
            NodeList nodeList = document.getElementsByTagName("className");
            Node node = null;
            if (args.equals("com.company.image.JPGImage")) {
                //獲取第一個節點
                node = nodeList.item(0).getFirstChild();
            } else if (args.equals("com.company.system.WindowsImp")) {
                //獲取第二個節點
                node = nodeList.item(1).getFirstChild();
            }
            String name = node.getNodeValue();
            //生成例項物件將其返回
            Class c = Class.forName(name);
            Object obj = c.newInstance();
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }
}

客戶端測試類

package com.company;

import com.company.image.Images;
import com.company.system.ImageImp;
import com.company.util.XMLUtil;

public class Client {

    public static void main(String[] args) {
   // write your code here
        Images images;
        ImageImp imageImp;
        images=(Images) XMLUtil.getBean("com.company.image.JPGImage");
        imageImp=(ImageImp) XMLUtil.getBean("com.company.system.WindowsImp");
        images.setImp(imageImp);
        images.parseFile("小龍女");
    }
}

轉載請註明出處,掌聲送給社會人