设计模式之builder模式

该模式也是常见的一种设计模式,即使你没用过它,也至少应该见过它。开发中我们经常使用各种开源框架,只要你有心分析其源码,就可以从中看出不少设计模式的影子,特别是本文的主角 Builder模式!博主经常阅读一些框架的源码,从中深有体会。
闲话少叙,本篇就来简单的掰扯掰扯这个设计模式。在面向对象的世界中,构建者模式构建的成品就是一个复杂的对象。这让我想起了小时候看的动漫恐龙战队,几个队员拿着不同的变身器分别组成机器人的不同部位,最终一步步的构建出一个超级机器人!
恐龙战队队员
机器人恐龙形态:
恐龙战队队员组成的机器人
所以从恐龙战队的例子可以看出构建者模式的意图之一就是:将一个复杂的构建与其表示相分离。另外面向对象的三大特征之一就是抽象!所以在设计框架的时候,抽象能力也算是一个框架优劣重要的体现。因为抽象的实现方式不同,构建的对象也不同。还是以恐龙战队来举例子,恐龙除了上面的恐龙形态外,还有人行形态,见下图:
在这里插入图片描述

这就是构建者模式的强大之处,只要抽象层做的好,不同的实现,可以构建出不同的对象。我觉得这方面Retrofit这个框架把构建者模式应用的淋漓尽致。看下图,我们可以构建出不同的CallAdapter和Converter,然后通过不同的Adapter和Converter来创建不同的Retrofit对象。(如果对Retrofit不了解的话可以参考博主的okhttp源码解析):
在这里插入图片描述
不知道大家注意到没有,一些常用的框架,比如Android的图片缓存框架,将缓存策略抽象出来,除了框架本身自带的缓存实现之外,也可以让客户端自定义缓存实现,最终在构建图片缓存对象的时候注入进来就可以了,见下图:
在这里插入图片描述

再比如网络请求Okhttp框架,其强大的拦截器的设计理念让我们在构建OkhttpClient对象的时候,可以添加自己的拦截器,比如统一打印的拦截器,添加统一参数的拦截器等等,最终会构建出不同的OkhttpClient对象,见下图:
在这里插入图片描述
其实模式不模式的不是最重要的,最重要的是抽象设计的能力,抽象做的好,对以后的扩展来说就很得心应手。说白了设计模式在我看来就是 抽象能力的具体展现罢了,不用谈模色变,也不同生搬硬套。另外构建者设计模式与其说是一个模式,不如说是一个思想,它可以杂糅其他的模式,比如构建者的部分对象用了模板,代理等模式都是有可能的,总的来说就是设计思想,对于构建者模式的组成部分来说,同样适用。

已标记关键词 清除标记
<div class="post-text" itemprop="text"> <p>I have a scenario like this:</p> <p>The system handles reservations from couple of different sources. All bookings come in the form of a json with differing formats for each source. Some JSON attributes are present in one JSON and not in the other etc.</p> <p>In order to enter the reservation into the system, I am trying to centralize the Add Reservation logic into one method. To do this, I am trying to create a class called Reservation using the Builder pattern as such:</p> <pre><code><?php namespace App\Business\Classes\Reservation; use App\Business\Classes\Utils\ReservationUtils; /** * Class Reservation * Holds entire reservation details * @package App\Business\Classes\Reservation */ class Reservation { protected $reference, $otaReference, $hotelCode, $customerId, $guestName, $couponId, $checkin, $checkout, $guests, $customerCountry, $commissionRate, $paymentStatus, $commissionOta, $commissionDifference, $rooms = [], $cityTax, $vat, $serviceCharge, $geniusBooker = false, $geniusAmount = 0, $taxes, $taxIncluded = false, $supplierAmount, $totalAmount, $specialRequest, $currency, $deviceType, $bookingSource, $otaRefId, $status, $source, $remarks; public function __construct() { // generates a reference $this->reference = ReservationUtils::referenceGenerator(); } /** * @param mixed $otaReference * @return Reservation */ public function setOtaReference($otaReference): Reservation { $this->otaReference = $otaReference; return $this; } /** * @param mixed $checkin * @return Reservation */ public function setCheckin($checkin): Reservation { $this->checkin = $checkin; return $this; } /** * @param mixed $checkout * @return Reservation */ public function setCheckout($checkout): Reservation { $this->checkout = $checkout; return $this; } /** * @param array $rooms * @return Reservation */ public function setRooms(array $rooms): Reservation { $this->rooms = $rooms; return $this; } // and so on.... } </code></pre> <p>And I would use it like this:</p> <pre><code>$data= json_decode($result->jsonData); $reservation = (new Reservation()) ->setOtaReference($data->otaReference) ->setCheckin($data->checkin) ->setCheckout($data->checkout); //...etc </code></pre> <p>This is probably not the textbook usage of the builder pattern in PHP or even Java but is there anything wrong with it?</p> <p>Thanks</p> </div>
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页
实付 19.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值