iT邦幫忙

2023 iThome 鐵人賽

DAY 15
0
Software Development

軟體架構備忘錄系列 第 15

Day 15 程式架構 - 結構型設計模式 (知識點076~079)

  • 分享至 

  • xImage
  •  

思考的問題

如何通過組合多的不同的類別與物件,完成複雜的需求?

當有複雜的需求時,有甚麼方法可以組合這些類別呢?
常見的方式包含:外觀模式、轉接器模式、裝飾者模式 以及組合模式


外觀模式

描述

外觀模式 (Facade pattern) 是一個十分常見的設計模式。它用於簡化複雜系統的使用,提供一個統一的、易於使用的界面,以避免直接使用複雜的底層元件。這可以提升系統或工具的易用性,並降低使用者或客戶端的耦合度。

使用情境

  • 簡化界面:當一個系統包含多個複雜的子系統或模組,可使用外觀模式。以讓使用者能夠更容易地與系統互動

案例

一個典型的外觀模式示例是Spring框架中的JDBCTemplate。JDBCTemplate封裝了複雜的資料庫訪問操作,使開發人員能夠通過簡單的API執行資料庫查詢、更新等操作,而無需關心底層的JDBC細節。

javaCopy code
// 使用JDBCTemplate執行資料庫操作
int result = jdbcTemplate.queryForObject(
    "SELECT COUNT(*) FROM EMPLOYEE", Integer.class);

jdbcTemplate.update(
    "INSERT INTO EMPLOYEE VALUES (?, ?, ?, ?)", id, "Bill", "Gates", "U

轉接器模式

描述

轉接器模式 (Adapter Pattern) 使用Adapter類別封裝原始類別的物件,將其轉換為Target Interface的形式。以轉換不同類別的實現為另一種形式。

使用情境

  • 封裝外部套件以增加新功能:想要使用外部套件,但是又希望調整其操作介面。可使用Adapter封裝外部套件並增加額外的功能。
  • 減少與外部套件的耦合:使用Adapter增加一個抽象層做為外部套件介接的窗口。可避免程式與外部套件的耦合度過高。後續外部套件版本更新時,可降低程式變更的風險。
  • 整合新舊系統:若新舊系統的介面不一致,可使用Adapter模式封裝舊系統功能,讓新的系統使用一致的介面與舊系統界接。

案例1

在SLF4j中使用Adapter模式,將不同Log套件的介面,封裝為統一形式,並且解耦對特定Log套件的綁定。

可透過SLF4j與 Logback、Log4J、java.util.logging等Log套件介接

public class Slf4jExample {
    //在SLF4J中,動態封裝不同套件的Log工具
    private static Logger logger = LoggerFactory.getLogger(Slf4jExample.class);

    public static void main(String[] args) {
        logger.debug("Debug log message");
        logger.info("Info log message");
        logger.error("Error log message");
    }
}

案例2

在Camunda sping中,封裝Jackson的JsonNode,以提供不同的初始化與使用方式

SpinJsonNode node = new SpinJsonNode();
node.put("name", "John Doe");
node.put("children", Arrays.asList("Mary", "Peter"));

案例3:整合新舊系統功能

有時需要使用舊有系統的功能,但是希望其使用方法與新系統一致,並且降低與舊系統的耦合度。

這時使用Adapter模式是一個很好的選擇

// 舊系統的類別
class OldSystem {
    public void legacyMethod() {
        System.out.println("Legacy Method in Old System");
    }
}

// 新系統期望的介面
interface NewSystemInterface {
    void newMethod();
}

// Adapter類別,將OldSystem轉換成NewSystemInterface
class OldSystemAdapter implements NewSystemInterface {
    OldSystem oldSystem = new OldSystem();

    @Override
    public void newMethod() {
        // 在Adapter中使用舊系統的實例        
        oldSystem.legacyMethod();
    }
}

//後續可使用新的介面使用舊的系統元件,甚至可讓使用者未察覺舊系統整合的差異。
NewSystemInterface adapter = new OldSystemAdapter();
adpter.newMethod();

裝飾者模式

描述

裝飾者模式 (Decorator Pattern) 通過動態地將裝飾者類與基本元件進行組合,來為對象增加不同的功能。這允許在不修改現有程式碼的情況下,為對象附加多種不同的功能。

使用情境

  • 多維度變化:使用情境有N * M 的多維度的變化,需要在執行階段動態地為對象新增功能。

案例

Java IO中,使用裝飾者模式 讓使用者彈性決定 讀取資料的模式

String filePath = "sample.txt";//檔案路徑
//讀取檔案的底層物件
FileInputStream fileInputStream = new FileInputStream(filePath);
//裝飾:使用Buffer讀取資料,以提升效能
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream));
//裝飾:提供各種資料格式的讀取
DataInputStream dataInputStream = new DataInputStream(bufferedInputStream)) {

int intValue = dataInputStream.readInt();
String stringValue = dataInputStream.readUTF();

組合模式

描述

組合模式 (Composite Pattern) 通過一個樹狀的物件結構,組合出一個複雜的資料描述。

使用情境

  • 樹狀結構物件:如果資料結構為樹狀,可以使用組合模式 搭配不同階層的節點物件類別。
  • 統一樹狀結構物件的接口:為了便於使用者使用與理解,使用類似的接口處理不同階層的樹狀物件

案例1

Apache POI的excel套件中,活頁簿、工作表、列、儲存格 就是一個以組合模式形成樹狀結構的經典案例

//建立Excel活頁簿
Workbook wb = new XSSFWorkbook();
//建立工作表
Sheet sheet = wb.createSheet("new sheet");
//建立Row
Row row = sheet.createRow(0);
//建立Cell,並且設定內容
Cell cell = row.createCell(0);
cell.setCellValue("Hello, World!");

案例2

Jackson套件中,使用JsonNode物件表示樹狀的JSON資料

每一個節點都是一個JsonNode,節點格式可能為下方格式

  • ObjectNode:表示JSON物件
  • ArrayNode:表示JSON陣列
  • NumberValue: 數字節點
  • TextValue: 文字節點
  • 其他格式

下方程式碼即可建立JSON物件

ObjectMapper objectMapper = new ObjectMapper();
        
// 建立一個 ObjectNode 來表示 JSON物件
ObjectNode jsonNode = objectMapper.createObjectNode();

// 設定JSON物件的屬性欄位
jsonNode.put("name", "John");
jsonNode.put("age", 30);
jsonNode.put("city", "New York");

// JSON物件其中一個屬性是陣列
ArrayNode languages = jsonNode.putArray("lang");
languages.add("English");
languages.add("Spanish");

對應的JSON資料如下

{
    "name": "John",
    "age": 30,
    "city": "New York",
    "languages": ["English", "Spanish"]
}

上一篇
Day 14 程式架構 - 創建型設計模式 (知識點072~075)
下一篇
Day 16 程式架構 - 行為型設計模式 (知識點080~084)
系列文
軟體架構備忘錄30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言