一、定義 為子系統中的一組介面提供一個一致的入口,外觀模式定義了一個高層介面,這個介面使得這一子系統更加容易使用。外觀模式是一種結構型模式。 二、描述 包含以下兩個角色:1、Facade(外觀角色):在客戶端可以調用它的方法,在外觀角色中可以知道相關的(一個或多個)子系統的功能和責任;在正常情況下, ...
一、定義
為子系統中的一組介面提供一個一致的入口,外觀模式定義了一個高層介面,這個介面使得這一子系統更加容易使用。外觀模式是一種結構型模式。
二、描述
包含以下兩個角色:1、Facade(外觀角色):在客戶端可以調用它的方法,在外觀角色中可以知道相關的(一個或多個)子系統的功能和責任;在正常情況下,它將所有從客戶端發來的請求委派到相應的子系統中去,傳遞給相應的子系統對象處理。
2、SubSystem(子系統角色):在軟體系統中可以有一個或者多個子系統角色,每一個子系統可以不是一個單獨的類,而是一個類的集合,它實現子系統的功能;每一個子系統都可以被客戶端直接調用,或者被外觀角色調用,它處理外觀類傳過來的請求;子系統並不知道外觀的存在,對於子系統而言,外觀角色僅僅是另一個客戶端而已。
三、例子
X公司想要開發一個可應用於多個軟體的文件加密模塊,該模塊可以對文件中的數據進行加密並將加密後的數據存儲在一個新文件中,具體的流程包括3個部分,分別是讀取源文件、加密、保存加密之後的文件。其中,讀取文件和保存文件使用流來實現,加密操作通過求模運算實現。這3個操作相對獨立,為了實現代碼地獨立重用,讓設計更加符合單一職責原則,這3個操作的業務代碼封裝在3個不同的類中。FileReader、CipherMachie、FileWriter:文件讀取類、數據加密類、文件保存類,充當子系統類
public class FileReader
{
public string Read(string fileNameSrc)
{
Console.WriteLine("讀取文件,獲取明文:");
FileStream fs = null;
StringBuilder sb = new StringBuilder();
try
{
fs = new FileStream(fileNameSrc, FileMode.Open);
int data;
while ((data = fs.ReadByte()) != -1)
{
sb.Append((char)data);
}
fs.Close();
Console.WriteLine(sb.ToString());
}
catch (FileNotFoundException e)
{
Console.WriteLine("文件不存在");
}
catch (IOException e)
{
Console.WriteLine("文件操作錯誤");
}
return sb.ToString();
}
}
public class CipherMachine
{
public string Encrypt(string plainText)
{
Console.WriteLine("數據加密,將明文轉換為密文:");
string es = "";
char[] chars = plainText.ToCharArray();
foreach (char ch in chars)
{
string c = (ch % 7).ToString();
es += c;
}
Console.WriteLine(es);
return es;
}
}
public class FileWriter
{
public void Write(string encryptedStr, string fileNameDes)
{
Console.WriteLine("保存密文,寫入文件");
FileStream fs = null;
StringBuilder sb = new StringBuilder();
try
{
fs = new FileStream(fileNameDes, FileMode.Create);
byte[] str = Encoding.Default.GetBytes(encryptedStr);
fs.Write(str, 0, str.Length);
fs.Flush();
fs.Close();
}
catch (FileNotFoundException e)
{
Console.WriteLine("文件不存在");
}
catch (IOException e)
{
Console.WriteLine(e.Message);
Console.WriteLine("文件操作錯誤");
}
}
}
EncrytFacade:外觀類
public class EncryptFacade
{
private FileReader reader;
private CipherMachine cipher;
private FileWriter writer;
public EncryptFacade()
{
reader = new FileReader();
cipher = new CipherMachine();
writer = new FileWriter();
}
public void FileEncrypt(string fileNameSrc, string fileNameDes)
{
string plainStr = reader.Read(fileNameSrc);
string encryptedStr = cipher.Encrypt(plainStr);
writer.Write(encryptedStr, fileNameDes);
}
}
Program:客戶端測試類
EncryptFacade facade = new EncryptFacade();
facade.FileEncrypt("src.txt", "des.txt");
Console.ReadLine();
四、總結
1、優點
(1)它對客戶端屏蔽了子系統組件,減少了客戶端需要處理的對象數目,並且使得子系統使用起來更加容易。通過引入外觀模式,客戶端代碼將變得很簡單,與之關聯的對象也很少。
(2)它實現了子系統與客戶端之間的松耦合關係,這使得子系統的變化不會影響到調用它的客戶端,只需要調整外觀類即可。
(3)一個子系統的修改對於其他子系統沒有任何影響,而且子系統的內部變化也不會影響到外觀對象。
2、缺點
(1)外觀模式不能很好地限制客戶端直接使用子系統類,如果對客戶端訪問子系統類做太多的限制則減少了可變性和靈活性。
(2)如果設計不當,增加新的子系統可能需要修改外觀類的源代碼,違背了開閉原則。