外觀模式(Facade)

@@@模式定義:
爲子系統中的一組接口提供一個一致的界面,Facade模式定義了一個高層接口,
這個接口使得這一子系統更加容易使用。


@@@練習示例: 
模擬一個代碼生成工具,來生成一個三層架構(表現層、邏輯層、數據層)的代碼。


@@@不用模式:
coder\ConfigModel.java                [描述配置的數據Model]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package coder;


/**
* 示意配置描述的數據Model,真實的配置數據會很多
*/
public class ConfigModel {
/**
*  是否需要生成表現層,默認是true
*/
private boolean needGenPresentation = true;


/**
*  是否需要生成邏輯層,默認是true
*/
private boolean needGenBusiness = true;


/**
*  是否需要生成DAO層,默認是true
*/
private boolean needGenDAO = true;


public boolean isNeedGenPresentation() {
return needGenPresentation;
}


public void setNeedGenPresentation(boolean needGenPrasentation) {
this.needGenPresentation = needGenPresentation;
}


public boolean isNeedGenBusiness() {
return needGenBusiness;
}


public void setNeedGenBusiness(boolean needGenBusiness) {
this.needGenBusiness = needGenBusiness;
}


public boolean isNeedGenDAO() {
return needGenDAO;
}


public void setNeedGenDAO(boolean needGenDAO) {
this.needGenDAO = needGenDAO;
}
}


coder\ConfigManager.java               [配置管理]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package coder;


/**
* 示意配置管理,就是負責讀取配置文件,
* 並把配置文件的內容設置到配置Model中去,是個單例
*/
public class ConfigManager {
private static ConfigManager manager = null;
private static ConfigModel   cm      = null;


private ConfigManager() {
   // 
}


public static ConfigManager getInstance() {
if (null == manager){
manager = new ConfigManager();
cm      = new ConfigModel();
// 讀取配置文件,把值設置到ConfigModel中去,此處省略
}


return manager;
}


/**
* 獲取配置的數據
* @return 配置的數據
*/
public ConfigModel getConfigData() {
return cm;
}
}


coder\Presentation.java                     [生成表現層的模塊]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


package coder;


/**
* 示意生成表現層的模塊
*/
public class Presentation {
public void generate() {
// 1. 從配置管理裏面獲取相應的配置信息
ConfigModel cm = ConfigManager.getInstance().getConfigData();
if(cm.isNeedGenPresentation()) {
// 2. 按照要求去生成相應的代碼,並保存成文件
System.out.println("正在生成表現層代碼文件");
}
}
}


coder\Business.java                 [生成邏輯層的模塊]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


package coder;


/**
* 示意生成邏輯層的模塊
*/
public class Business {
public void generate() {
// 1. 從配置管理裏面獲取相應的配置信息
ConfigModel cm = ConfigManager.getInstance().getConfigData();
if(cm.isNeedGenBusiness()) {
// 2. 按照要求去生成相應的代碼,並保存成文件
System.out.println("正在生成邏輯層代碼文件");
}
}
}


coder\DAO.java               [生成數據層的模塊]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


package coder;


/**
* 示意生成數據層的模塊
*/
public class DAO {
public void generate() {
// 1. 從配置管理裏面獲取相應的配置信息
ConfigModel cm = ConfigManager.getInstance().getConfigData();
if(cm.isNeedGenDAO()) {
// 2. 按照要求去生成相應的代碼,並保存成文件
System.out.println("正在生成數據層代碼文件");
}
}
}




user\Client.java          [客戶端實現]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


package user;


import coder.Presentation;
import coder.Business;
import coder.DAO;


public class Client {
public static void main(String[] args) {
/*
* 現在沒有配置文件,直接使用默認配置,通常情況下,三層都應該生成
* 也就是說客戶端必須對這些模塊都瞭解,才能夠正確使用它們
*/
new Presentation().generate();
new Business().generate();
new DAO().generate();
}
}


@@@存在問題:
客戶端爲了使用生成代碼的功能,需要與生成代碼子系統內部的多個模塊交互。違反了LKP。
導致客戶端使用代碼生成功能時比較複雜,並且,如果其中某個模塊發生變化後可能會導致客戶端也需要隨着其變化。


@@@使用模式:
代碼生成模塊中,新增一個Facade類,其他不變。
coder\Facade.java              [模塊的外觀]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


package coder;


/**
* 代碼生成子系統的外觀類
*/
public class Facade {
/**
* 客戶端需要的,一個簡單的調用代碼生成的功能
*/
public void generate() {
new Presentation().generate();
new Business().generate();
new DAO().generate();
}
}


user\Client.java                [客戶端實現]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


package user;


import coder.Facade;


public class Client {
public static void main(String[] args) {
// 使用Facade
new Facade().generate();
}
}


此時,客戶端不再需要知道代碼生成模塊中的各個子模塊,
只需要知道使用代碼生成模塊的外觀類的generate方法來生成代碼即可。
體現了最少知識原則,也是以客戶爲中心的做法。


@@@外觀模式的實現:
(1)Facade通常可以實現成爲一個單例;
(2)Facade也可以實現成爲一個接口;
(3)Facade中的方法通常可以實現爲靜態方法;
(4)Facade中的方法一般只進行組合調用,其本身並不進行功能處理;


@@@外觀模式的優點:
鬆散耦合
簡單易用
更好地劃分訪問的層次


@@@外觀模式的缺點:
過多的或者是不太合理的Facade容易讓人迷惑。到底是調用Facade好呢,還是直接調用模塊好。


@@@外觀模式的本質:
封裝交互,簡化調用。


@@@外觀模式體現的設計原則:

最少知識原則



發佈了28 篇原創文章 · 獲贊 5 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章