1. 程式人生 > >Java設計模式之外觀模式(門面模式)

Java設計模式之外觀模式(門面模式)

什麼是外觀模式

  外觀模式(Facade),他隱藏了系統的複雜性,並向客戶端提供了一個可以訪問系統的介面。這種型別的設計模式屬於結構性模式。為子系統中的一組介面提供了一個統一的訪問介面,這個介面使得子系統更容易被訪問或者使用。 

外觀模式應用場景

簡單來說,該模式就是把一些複雜的流程封裝成一個介面供給外部使用者更簡單的使用。這個模式中,設計到3個角色。

1.門面角色:外觀模式的核心。它被客戶角色呼叫,它熟悉子系統的功能。內部根據客戶角色的需求預定了幾種功能的組合。

2.子系統角色:實現了子系統的功能。它對客戶角色和Facade時未知的。它內部可以有系統內的相互互動,也可以由供外界呼叫的介面。

3.客戶角色:通過呼叫Facede來完成要實現的功能。

相關程式碼實現

需要重構程式碼

@Slf4j
@Component
public class PayCallbackService {
    // 使用者下單成功後,有那些操作?
    // 1.增加支付回撥介面日誌
    // 2.修改訂單資料庫狀態為已經成功
    // 3.呼叫積分服務介面
    // 4.呼叫訊息服務平臺服務介面

    public boolean callback(Map<String, String> verifySignature) {
        // 1.第一步列印日誌資訊
        String orderId = verifySignature.get("orderId"); // 獲取後臺通知的資料,其他欄位也可用類似方式獲取
        String respCode = verifySignature.get("respCode");
        log.info("orderId:{},respCode:{}", orderId, respCode);
        // 2.修改訂單狀態為已經支付
        new PaymentTransactionMapper() {
            @Override
            public void updatePaymentStatus() {
                log.info(">>>修改訂單狀態為已經支付>>>>>");
            }
        }.updatePaymentStatus();
        // 3.呼叫積分介面增加積分
        HttpClientUtils.doPost("jifen.com", "積分介面");
        // 4.呼叫訊息服務平臺提示
        HttpClientUtils.doPost("msg.com", "呼叫訊息介面");
        return true;
    }
}

utils

@Slf4j
public class HttpClientUtils {

    public static String doPost(String url, String text) {
        log.info(">>>Url:{},text:{}", url, text);
        return "success";
    }
}

建立業務邏輯封裝

@Slf4j
@Component
public class LogService {

    public void log(Map<String, String> verifySignature) {
        String orderId = verifySignature.get("orderId"); // 獲取後臺通知的資料,其他欄位也可用類似方式獲取
        String respCode = verifySignature.get("respCode");
        log.info("1.第一個模組,列印日誌模組:orderId:{},respCode:{}", orderId, respCode);
    }
}
@Slf4j
@Component
public class PaymentService {

    public void updatePaymentStatus() {
        // 2.修改訂單狀態為已經支付
        new PaymentTransactionMapper() {
            @Override
            public void updatePaymentStatus() {
                log.info(2."第二個模組>>>修改訂單狀態為已經支付>>>>>");
            }
        }.updatePaymentStatus();
    }
}
@Component
@Slf4j
public class IntegralService {

    public void callIntegral() {
        // 3.呼叫積分介面增加積分
        HttpClientUtils.doPost("jifen.com", "積分介面");
        log.info("3.第三個模組>>>呼叫積分介面列印日誌>>>>>");
    }
}
@Component
@Slf4j
public class MsgService {

    public void callMsg() {
        log.info("4.第四個模組 呼叫訊息模組");
        HttpClientUtils.doPost("msg.com", "呼叫訊息介面");
    }
}

建立門面介面:PayFacade 

@Component
public class PayFacade {
    @Autowired
    private LogService logService;
    @Autowired
    private PaymentService paymentService;
    @Autowired
    private IntegralService integralService;
    @Autowired
    private MsgService msgService;

    public String callback(Map<String, String> verifySignature) {
        logService.log(verifySignature);
        paymentService.updatePaymentStatus();
        integralService.callIntegral();
        msgService.callMsg();
        return "success";
    }
}

PayCallbackController 

@RestController
public class PayCallbackController {
    @Autowired
    private PayFacade payFacade;

    @RequestMapping("/callback")
    public String callback(@RequestBody Map<String, String> verifySignature) {
        String result = payFacade.callback(verifySignature);
        return result;
    }
}

mapper

public interface PaymentTransactionMapper {
    void updatePaymentStatus();
}

啟動類

@SpringBootApplication
public class AppFacade {
    public static void main(String[] args) {
        SpringApplication.run(AppFacade.class);
    }
}

pom

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>
    <dependencies>
        <!-- sprinboot web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>

    </dependencies>

使用postman進行測試

控制檯輸出

2019-05-25 23:12:54.773  INFO 1948 --- [nio-8080-exec-6] com.xuyu.service.LogService              : 1.第一個模組,列印日誌模組:orderId:111,respCode:xuyucode
2019-05-25 23:12:54.774  INFO 1948 --- [nio-8080-exec-6] com.xuyu.service.PaymentService          : 2.第二個模組>>>修改訂單狀態為已經支付>>>>>
2019-05-25 23:12:54.775  INFO 1948 --- [nio-8080-exec-6] com.xuyu.service.IntegralService         : 3.第三個模組 呼叫積分模組
2019-05-25 23:12:54.775  INFO 1948 --- [nio-8080-exec-6] com.xuyu.utils.HttpClientUtils           : >>>Url:jifen.com,text:積分介面
2019-05-25 23:12:54.775  INFO 1948 --- [nio-8080-exec-6] com.xuyu.service.MsgService              : 4.第四個模組 呼叫訊息模組
2019-05-25 23:12:54.775  INFO 1948 --- [nio-8080-exec-6] com.xuyu.utils.HttpClientUtils           : >>>Url:msg.com,text:呼叫訊息介面
success