今天我們來(lái)講一下PHP中的DDD(領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)),DDD旨在將業(yè)務(wù)邏輯和底層技術(shù)分離,使得設(shè)計(jì)更加模塊化、可擴(kuò)展性更好。下面,我們就通過一個(gè)例子來(lái)感受下DDD實(shí)戰(zhàn)。
舉個(gè)例子,假設(shè)我們現(xiàn)在有一個(gè)電商網(wǎng)站,用戶在下單購(gòu)買商品后需要付款,我們需要實(shí)現(xiàn)這個(gè)付款的邏輯。首先,我們需要判斷用戶支付方式是否正確,然后根據(jù)用戶的支付方式進(jìn)行相應(yīng)的邏輯處理,最后需要更新訂單狀態(tài)?,F(xiàn)在讓我們一步步分析如何用DDD來(lái)實(shí)現(xiàn)這個(gè)需求。
首先,我們需要定義一個(gè)Order領(lǐng)域模型,Order包含了用戶選擇的商品信息、支付方式、訂單狀態(tài)等信息,其中訂單狀態(tài)-OrderStatus是一個(gè)枚舉類型,可以表示訂單狀態(tài),如未支付、已支付、已發(fā)貨等。這里我們來(lái)看一下Order的代碼實(shí)現(xiàn):
class Order { /** * 訂單編號(hào) */ private $orderNo; /** * 訂單狀態(tài) */ private $status; /** * 商品信息 */ private $products; /** * 支付方式 */ private $payMethod; /** * Order constructor. * @param $orderNo * @param $payMethod * @param $products * @param $status */ public function __construct($orderNo, $payMethod, $products, $status) { $this->orderNo = $orderNo; $this->payMethod = $payMethod; $this->products = $products; $this->status = $status; } /** * 獲取訂單編號(hào) * @return mixed */ public function getOrderNo() { return $this->orderNo; } /** * 獲取訂單狀態(tài) * @return mixed */ public function getStatus() { return $this->status; } /** * 獲取商品列表 * @return mixed */ public function getProducts() { return $this->products; } /** * 獲取支付方式 * @return mixed */ public function getPayMethod() { return $this->payMethod; } /** * 更新訂單狀態(tài) * @param $status */ public function updateStatus($status) { $this->status = $status; } }接下來(lái),我們需要定義一個(gè)支付服務(wù)PayService,用于支付相關(guān)操作,其中包括了檢查支付方式和更新訂單狀態(tài)等操作。PayService依賴于OrderRepository和PayGateway,其中OrderRepository用于查詢訂單信息,PayGateway用于實(shí)現(xiàn)支付邏輯,這里我們來(lái)看一下PayService的代碼實(shí)現(xiàn):
class PayService { /** * @var OrderRepository */ private $orderRepository; /** * @var PayGateway */ private $payGateway; /** * PayService constructor. * @param OrderRepository $orderRepository * @param PayGateway $payGateway */ public function __construct(OrderRepository $orderRepository, PayGateway $payGateway) { $this->orderRepository = $orderRepository; $this->payGateway = $payGateway; } /** * 支付訂單 * @param $orderNo * @param $payMethod * @return bool */ public function payOrder($orderNo, $payMethod) { // 查詢訂單信息 $order = $this->orderRepository->getOrderByOrderNo($orderNo); // 檢查支付方式 if (!$this->checkPayMethod($order, $payMethod)) { throw new \Exception("支付方式不正確"); } // 實(shí)現(xiàn)支付邏輯 $result = $this->payGateway->pay($order, $payMethod); // 更新訂單狀態(tài) if ($result) { $order->updateStatus(OrderStatus::PAID); $this->orderRepository->save($order); return true; } return false; } /** * 檢查支付方式 * @param $order * @param $payMethod * @return bool */ private function checkPayMethod($order, $payMethod) { if ($order->getPayMethod() == $payMethod) { return true; } return false; } }最后,我們需要定義一個(gè)訂單倉(cāng)庫(kù)OrderRepository,用于查找訂單信息,這里我們假設(shè)訂單信息存在于數(shù)據(jù)庫(kù)中,我們需要使用PDO實(shí)現(xiàn)相關(guān)數(shù)據(jù)庫(kù)操作,這里我們來(lái)看一下OrderRepository的代碼實(shí)現(xiàn):
class OrderRepository { /** * @var PDO */ private $pdo; /** * OrderRepository constructor. * @param PDO $pdo */ public function __construct(PDO $pdo) { $this->pdo = $pdo; } /** * 根據(jù)訂單號(hào)獲取訂單信息 * @param $orderNo * @return Order */ public function getOrderByOrderNo($orderNo) { $stmt = $this->pdo->prepare("SELECT * FROM `order` WHERE order_no = :orderNo"); $stmt->bindParam(":orderNo", $orderNo); $stmt->execute(); $row = $stmt->fetch(PDO::FETCH_ASSOC); if ($row) { return new Order($row['order_no'], $row['pay_method'], $row['products'], $row['status']); } return null; } /** * 保存訂單信息 * @param Order $order * @return bool */ public function save(Order $order) { $stmt = $this->pdo->prepare("UPDATE `order` SET status=:status WHERE order_no = :orderNo"); $stmt->bindParam(":status", $order->getStatus()); $stmt->bindParam(":orderNo", $order->getOrderNo()); return $stmt->execute(); } }通過以上三個(gè)部分的實(shí)現(xiàn),我們就可以完成整個(gè)付款的邏輯處理了。我們可以看到,通過DDD的思想,我們將業(yè)務(wù)邏輯和底層技術(shù)進(jìn)行了分離,每一個(gè)部分都具有自己的職責(zé),模塊化、可擴(kuò)展性都得到了很好的保證。