處理多維度變化——橋接模式(三)

Liuwei-Sunny發表於2012-04-16

10.3  完整解決方案

        為了減少所需生成的子類數目,實現將作業系統和影象檔案格式兩個維度分離,使它們可以獨立改變,Sunny公司開發人員使用橋接模式來重構跨平臺影象瀏覽系統的設計,其基本結構如圖10-5所示:

         在圖10-5中,Image充當抽象類,其子類JPGImagePNGImageBMPImageGIFImage充當擴充抽象類;ImageImp充當實現類介面,其子類WindowsImpLinuxImpUnixImp充當具體實現類。完整程式碼如下所示:
//畫素矩陣類:輔助類,各種格式的檔案最終都被轉化為畫素矩陣,不同的作業系統提供不同的方式顯示畫素矩陣
class Matrix {
	//此處程式碼省略
}

//抽象影象類:抽象類
abstract class Image {
	protected ImageImp imp;

	public void setImageImp(ImageImp imp) {
		this.imp = imp;
	} 

	public abstract void parseFile(String fileName);
}

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

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

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

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

//JPG格式影象:擴充抽象類
class JPGImage extends Image {
	public void parseFile(String fileName) {
        //模擬解析JPG檔案並獲得一個畫素矩陣物件m;
        Matrix m = new Matrix(); 
        imp.doPaint(m);
        System.out.println(fileName + ",格式為JPG。");
    }
}

//PNG格式影象:擴充抽象類
class PNGImage extends Image {
	public void parseFile(String fileName) {
        //模擬解析PNG檔案並獲得一個畫素矩陣物件m;
        Matrix m = new Matrix(); 
        imp.doPaint(m);
        System.out.println(fileName + ",格式為PNG。");
    }
}

//BMP格式影象:擴充抽象類
class BMPImage extends Image {
	public void parseFile(String fileName) {
        //模擬解析BMP檔案並獲得一個畫素矩陣物件m;
        Matrix m = new Matrix(); 
        imp.doPaint(m);
        System.out.println(fileName + ",格式為BMP。");
    }
}

//GIF格式影象:擴充抽象類
class GIFImage extends Image {
	public void parseFile(String fileName) {
        //模擬解析GIF檔案並獲得一個畫素矩陣物件m;
        Matrix m = new Matrix(); 
        imp.doPaint(m);
        System.out.println(fileName + ",格式為GIF。");
    }
}

        為了讓系統具有更好的靈活性和可擴充套件性,我們引入了配置檔案,將具體擴充抽象類和具體實現類類名都儲存在配置檔案中,再通過反射生成物件,將生成的具體實現類物件注入到擴充抽象類物件中,其中,配置檔案config.xml的程式碼如下所示:

<?xml version="1.0"?>
<config>
	<!--RefinedAbstraction-->
	<className>JPGImage</className> 
	<!--ConcreteImplementor-->
	<className>WindowsImp</className>
</config>

        用於讀取配置檔案config.xml並反射生成物件的XMLUtil類的程式碼如下所示:

import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import java.io.*;
public class XMLUtil {
//該方法用於從XML配置檔案中提取具體類類名,並返回一個例項物件
	public static Object getBean(String args) {
		try {
			//建立文件物件
			DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = dFactory.newDocumentBuilder();
			Document doc;							
			doc = builder.parse(new File("config.xml")); 
			NodeList nl=null;
			Node classNode=null;
			String cName=null;
			nl = doc.getElementsByTagName("className");
			
			if(args.equals("image")) {
				//獲取第一個包含類名的節點,即擴充抽象類
	            classNode=nl.item(0).getFirstChild();
	            
			}
			else if(args.equals("os")) {
			   //獲取第二個包含類名的節點,即具體實現類
	            classNode=nl.item(1).getFirstChild();
			}
			
	         cName=classNode.getNodeValue();
	         //通過類名生成例項物件並將其返回
	         Class c=Class.forName(cName);
		  	 Object obj=c.newInstance();
	         return obj;		
           }   
           catch(Exception e) {
              e.printStackTrace();
              return null;
          }
     }
}

        編寫如下客戶端測試程式碼:

class Client {
	public static void main(String args[]) {
		Image image;
		ImageImp imp;
		image = (Image)XMLUtil.getBean("image");
		imp = (ImageImp)XMLUtil.getBean("os");
		image.setImageImp(imp);
		image.parseFile("小龍女");
	}
}

        編譯並執行程式,輸出結果如下:

Windows作業系統中顯示影象:小龍女,格式為JPG

        如果需要更換影象檔案格式或者更換作業系統,只需修改配置檔案即可,在實際使用時,可以通過分析影象檔案格式字尾名來確定具體的檔案格式,在程式執行時獲取作業系統資訊來確定作業系統型別,無須使用配置檔案。當增加新的影象檔案格式或者作業系統時,原有系統無須做任何修改,只需增加一個對應的擴充抽象類或具體實現類即可,系統具有較好的可擴充套件性,完全符合“開閉原則”。

【作者:劉偉  http://blog.csdn.net/lovelion

相關文章