結構型設計模式實驗
1.介面卡模式例項之演算法適配
現有一個介面DataOperation定義了排序方法sort(int[])和查詢方法search(int[],int),已知類QuickSort的quickSort(int[])方法實現了快速排序演算法,類BinarySearch的binarySearch(int[],int)方法實現了二分查詢演算法。現使用介面卡模式設計一個系統,在不修改原始碼的情況下將類QuickSort和類BinarySearch的方法適配到DataOperation介面中。繪製類圖並程式設計實現。
2.橋接模式例項之跨平臺視訊播放器
如果需要開發一個跨平臺視訊播放器,可以在不同作業系統平臺(如
3.組合模式例項之防毒軟體
使用組合模式設計一個防毒軟體(AntiVirus)的框架,該軟體既可以對某個資料夾(Folder)防毒,也可以對某個指定的檔案(File)進行防毒,檔案種類包括文字包括TextFile、圖片檔案ImageFile、視訊檔案VideoFile。繪製類圖並程式設計模擬實現。
4.裝飾模式例項之介面顯示構件庫
某軟體公司基於面向物件技術開發了一套圖形介面顯示構件庫VisualComponent。在使用該庫構建某圖形介面時,使用者要求為介面定製一些特效顯示效果,如帶滾動條的窗體或透明窗體等。現使用裝飾模式設計該構件庫,繪製類圖並程式設計模擬實現。
5.外觀模式例項之檔案加密
某系統需要提供一個檔案加密模組,加密流程包括三個操作,分別是讀取原始檔、加密、儲存加密之後的檔案。讀取檔案和儲存檔案使用流來實現,這三個操作相對獨立,其業務程式碼封裝在三個不同的類中。現在需要提供一個統一的加密外觀類,使用者可以直接使用該加密外觀類完成檔案的讀取、加密和儲存三個操作,而不需要與每一個類互動,使用外觀模式設計該加密模組,要求程式設計模擬實現。
6.代理模式例項之日誌記錄代理
在某應用軟體中需要記錄業務方法的呼叫日誌,在不修改現有業務類的基礎上為每一個類提供一個日誌記錄代理類,在中輸出日誌,如在業務方法method()呼叫之前輸出
類圖
程式碼:
public interface DataOperation { //目標類
public void sort(int sort[], int i, int j);
public int search(int search[], int n);
}
public class AlgotithmAdapter implements DataOperation{ //介面卡類
private QuickSort quick;
private BinarySearch binary;
public AlgotithmAdapter(QuickSort quick) {
this.quick = quick;
}
public AlgotithmAdapter(BinarySearch binary) {
this.binary = binary;
}
public void sort(int sort[], int i, int j) {
quick.quickSort(sort, i, j);
}
public int search(int search[], int n) {
return binary.binarySearch(search, n);
}
}
public class QuickSort { //適配者類
//劃分陣列
int partion(int array[], int p, int r) {
int x = array[r];
int i = p - 1;//注意這點,把i設成負值,然後作為移動的標誌
int j;
for (j = p; j < r; j++) {
if (array[j] <= x) {
i++;
int temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
int temp = array[j];
array[j] = array[i + 1];
array[i + 1] = temp;
return i+1;//返回的應該是交換後的哨兵的位置
}
//遞迴解決每個劃分後的小陣列
void quickSort(int[] array, int p, int r) {
if (p < r) {
int q = partion(array, p, r);
quickSort(array, p, q - 1);
quickSort(array, q + 1, r);
}
}
}
public class BinarySearch { //適配者類
public int binarySearch(int[] srcArray, int des){
int low = 0;
int high = srcArray.length-1;
while(low <= high) {
int middle = (low + high)/2;
if(des == srcArray[middle]) {
return middle;
}else if(des <srcArray[middle]) {
high = middle - 1;
}else {
low = middle + 1;
}
}
return -1;
}
}
public class Client { //客戶端類
public static void main(String[] args) {
int[] array = { 4, 3, 5, 2, 3, 6, 8, 9, 18, 12, 53, 20};
int i;
System.out.print("排序前:");
for (i=0; i<array.length; i++)
System.out.print(array[i]+" ");
BinarySearch binary = new BinarySearch();
AlgotithmAdapter algotithm1 = new AlgotithmAdapter(binary);
System.out.println("\n通過二分查詢得到數字5:位於陣列的第"+(algotithm1.search(array, 5)+1)+"位");
QuickSort sort = new QuickSort();
AlgotithmAdapter algotithm2 = new AlgotithmAdapter(sort);
algotithm2.sort(array, 0, array.length - 1);
System.out.println("------------------------------");
System.out.print("排序後:");
for (i=0; i<array.length; i++)
System.out.print(array[i]+" ");
//int[] src = new int[] {1, 3, 5, 7, 8, 9};
System.out.println("\n通過二分查詢得到數字5:位於陣列的第"+(algotithm1.search(array, 5)+1)+"位");
}
}
二、橋接模式
Uml
原始碼
AVIFile:
package Bridge;
public class AVIFile implements VideoFile{
public void decode(String osType, String fileName) {
System.out.println("作業系統:"+osType+"檔名稱:"+fileName);
}
}
LinuxVersion:
package Bridge;
public class LinuxVersion extends OperatingSystemVersion {
public void play(String fileName) {
String osType = "Linux播放";
this.vf.decode(osType,fileName);
}
}
MPEGFile:
package Bridge;
public class MPEGFile implements VideoFile{
public void decode(String osType, String fileName) {
System.out.println("作業系統:"+osType+"檔名稱:"+fileName);
}
}
OperatingSystemVersion:
package Bridge;
public abstract class OperatingSystemVersion {
protected VideoFile vf;
public void setVideo(VideoFile vf) {
this.vf = vf;
}
public abstract void play(String fileName);
}
RMVBFile:
package Bridge;
public class RMVBFile implements VideoFile {
public void decode(String osType, String fileName) {
System.out.println("作業系統:"+osType+"檔名稱:"+fileName);
}
}
Test:
package Bridge;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
VideoFile vf;
OperatingSystemVersion osType1 = new WindowVersion();
vf = new AVIFile();
osType1.setVideo(vf);
osType1.play("AVI");
OperatingSystemVersion osType2 = new LinuxVersion();
vf = new RMVBFile();
osType2.setVideo(vf);
osType2.play("RMVB");
OperatingSystemVersion osType3 = new UnixVersion();
vf = new MPEGFile();
osType3.setVideo(vf);
osType3.play("MPEG");
}
}
UnixVersion:
package Bridge;
public class UnixVersion extends OperatingSystemVersion {
public void play(String fileName) {
String osType = "Unix播放";
this.vf.decode(osType,fileName);
}
}
VideoFile:
package Bridge;
public interface VideoFile {
public void decode(String osType, String fileName);
}
WindowVersion:
package Bridge;
public class WindowVersion extends OperatingSystemVersion {
public void play(String fileName) {
String osType = "Windows播放";
this.vf.decode(osType,fileName);
}
}
WMVFile:
package Bridge;
public class WMVFile implements VideoFile {
public void decode(String osType, String fileName) {
System.out.println("作業系統:"+osType+"檔名稱:"+fileName);
}
}
四、外觀模式
Uml
程式碼:
(1)Client類:
publicclass Client {
publicstaticvoid main(String[] args) {
try
{
String text="czy";
String address="c:設計模式";
EncryptFacade ec=new EncryptFacade();
ec.fileEncrypt(text,address);
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
(2)EncryptFacade類:
publicclass EncryptFacade {
private FileReader reader;
private CipherMachine cipher;
private FileWriter writer;
public EncryptFacade()
{
reader=new FileReader();
cipher=new CipherMachine();
writer=new FileWriter();
}
publicvoid fileEncrypt(String fileNameSrc,String fileNameDes)
{
String plainStr=reader.read(fileNameSrc);
String encryptStr=cipher.encrypt(plainStr);
writer.write(encryptStr,fileNameDes);
}
}
(3)FileReader類:
publicclass FileReader {
public String read(String fileNameSrc)
{
String fns=fileNameSrc;
System.out.println("原檔案:"+fns);
return fns;
}
}
(4)FileWriter類:
publicclass FileWriter {
publicvoid write(String EncryText,String FileNameDes)
{
String et=EncryText;
String fnd=FileNameDes;
System.out.println("加密後文件:"+et);
System.out.println("目標檔案存放路徑為:"+fnd);
}
}
(5)CipherMachine類:
publicclass CipherMachine {
public String encrypt(String plainText)
{
String str="";
for (int i=0;i<plainText.length();i++)
{
char c= plainText.charAt(i);
if(c>='a'&&c<='z')
{
c+=6;
if(c>'z')c-=26;
if(c<'a')c+=26;
}
if(c>='A'&&c<='Z')
{
c+=6;
if(c>'Z')c-=26;
if(c<'A')c+=26;
}
str+=c;
}
return str;
}
}
五、代理模式
uml圖
原始碼:
Log:
package proxy;
public interface Log {
public void method();
}
LogProxy:
package proxy;
import java.text.SimpleDateFormat;
import java.util.Date;
public class LogProxy implements Log{
private LogRecord logRecord=new LogRecord();
private SimpleDateFormat SDF=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private String time=SDF.format(new Date());
public void method() {
System.out.println("方法method被呼叫!呼叫時間為:"+time);
try{
logRecord.method();
System.out.println("方法method()呼叫成功!");
}catch(Exception e){
System.out.println("方法method()呼叫失敗!");
}
}
}
LogRecord:
package proxy;
public class LogRecord implements Log{
public void method() {
System.out.println("真實業務方法被呼叫!");
}
}
Test:
package proxy;
public class Test {
public static void main(String[] args) {
LogProxy p= new LogProxy();
p.method();
}
}