<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ### 簡介 這個類要放到哪兒?這可能是基于框架構建應用時非常常見的問題。很多開發者都會有這個疑問,因為他們被灌輸了「模型」就是「數據庫」這種概念。因此,在控制器里面處理 HTTP 請求,在模型類里面操作數據庫增刪改查,在視圖里編寫要顯示的HTML,成了開發者們約定俗成的規定。但是,發送電子郵件的類要放到哪兒?驗證數據的類呢?調用外部 API 的類呢?在這一章中,我們將介紹 Laravel 框架中良好的應用結構,并打破那些常見的阻止開發者做出好設計的心理障礙。 ### MVC是慢性謀殺 阻止開發者做出好設計的最大攔路虎就是一個簡單的首字母縮寫詞:M-V-C。模型(Model)、視圖(View)、控制器(Controller)已經統治 Web 框架的設計思想好多年了。這種思想的泛濫某種程度上因為 Ruby on Rails 的流行。然而,如果你問一個開發者「模型」的定義是什么,通常,你會聽到他嘟噥著什么「數據庫」之類的東西。這么說,模型就是數據庫了。不管這意味著什么,模型里包含了關于數據庫的一切。但是,你很快就會知道,你的應用程序需要的不僅僅是一個簡單的數據庫訪問類。它需要更多的邏輯,如數據驗證、調用外部服務、發送電子郵件等等。 > 「模型」這個單詞的含義太模糊了,以至于顯得沒有任何意義。更具體來講,模型是用來將我們的應用劃分成更小、更清晰的類,使得各代碼部分有著明確的權責。 所以,怎么解決這個問題呢?很多開發者開始將業務邏輯封裝到控制器里面。當控制器龐大到一定規模,它們將會需要復用其他控制器中的業務邏輯。大部分開發人員并沒有將這些業務邏輯提取到另外的類里面,而是錯誤的以為需要在控制器里面調用其他的控制器方法。這種模式通常被稱為「HMVC」。遺憾的是,這種模式通常也意味著糟糕的程序設計,以及控制器太過復雜。 > HMVC 意味著糟糕的設計:你覺得需要在控制器里面調用其他的控制器?這通常意味著糟糕的程序設計,以及你的控制器里面包含了過多的業務邏輯。好的做法是把控制器中的業務邏輯提取出來,放到一個新的第三方類里面,通常,我們將這種第三方類稱之為服務類,這樣你就可以在所有其他控制器里面注入服務類并使用它們了。 有一種更好的方式來構建應用程序結構。但首先我們要忘掉以往我們被灌輸的關于「模型」的一切。干脆點,讓我們直接刪掉模型目錄,重新開始吧! ### 再見,模型 刪掉你的 `models` 目錄了嗎?還沒刪就趕緊刪了!我們將要在 `app` 目錄下創建一個新的目錄,目錄名就以我們這個應用的名字來命名,比如 `QuickBill`。我們將繼續使用在前面章節中編寫的那些接口和類。 > 注意使用場景:記住,如果你在構建一個很小的 Laravel 應用,那在`models` 目錄下寫幾個 Eloquent 模型其實挺合適的。但在本章節,我們主要關注如何開發適用于分層架構的大型復雜項目。 所以,我們現在有了個 `app/QuickBill` 目錄,它和應用目錄下的其他目錄如 `Http` 還有 `Console` 都是平級的。在 `QuickBill` 目錄下我們還可以創建幾個其他目錄,例如 `Repositories` 和 `Billing` 目錄。目錄都創建好以后,別忘了在 `composer.json` 文件里通過 PSR-4 自動載入機制將它們注冊到 `QuickBill` 命名空間下: ```php "autoload": { "classmap": [ "database/seeds", "database/factories" ], "psr-4": { "App\\": "app/", "QuickBill\\": "app/QuickBill" } }, ``` 現在,我們把所有 Eloquent 模型類都放到 `QuickBill` 目錄下面。這樣我們就能很方便的以 `QuickBill\User`、`QuickBill\Payment` 這種方式來使用它們。`Repositories` 目錄下包含 `PaymentRepository` 和`UserRepository` 這種倉庫類,倉庫類里面包含了所有對數據的訪問功能,比如 `getRecentPayments` 和 `getRichestUser`。`Billing` 目錄包含了調用第三方支付服務(如 Stripe 和 Balanced)的類和接口。整個目錄結構現在應該類似這樣: ```php // app // QuickBill // Repositories -> UserRepository.php -> PaymentRepository.php // Billing -> BillerInterface.php -> StripeBiller.php // Notifications -> BillingNotifierInterface.php -> SmsBillingNotifier.php User.php Payment.php ``` > 數據驗證放在哪?在哪兒進行數據驗證常常困擾著開發人員。可以考慮將數據驗證方法寫進你的「實體」類里面(例如 `User.php` 和 `Payment.php`)。方法名可以設置為 `validForCreation` 或 `hasValidDomain`。或者你也可以專門創建一個驗證器類 `UserValidator`,放到 `Validation` 命名空間下,然后將這個驗證器類注入到你的 Repository 類里面。兩種方式你都可以試試,看哪個你更喜歡!當然在 Laravel 5.* 中,你不需要自己創建驗證器類了,通過 Laravel 自帶的驗證器類就可以滿足你的所有需求。 擺脫了 `models` 目錄的束縛后,你通常就能克服實現好的架構設計的心理障礙,也就能夠構建一個更合適應用的目錄結構。當然,你構建的每一個應用程序都會有一定的相似之處,因為不管多復雜的應用程序都需要一個數據訪問層(Repository),以及一些外部服務層等等。 > 別害怕目錄:不要懼怕創建更多目錄來組織管理應用。將整個應用切割成多個細分的功能組件總是必要的,每一個功能組件都專注于某一項職責。跳出「模型」的框框來思考總是有幫助的。例如,我們之前就討論過,你可以創建一個 `Repositories` 目錄來存放所有的數據訪問類。 ### 核心思想就是分層 你可能已經注意到,優化應用目錄結構的關鍵就是對不同組件的責任進行劃分,或者說為不同的職責創建不同的層。控制器只負責接收和響應 HTTP 請求,然后調用合適的業務邏輯層的類。你的業務邏輯/領域邏輯層才是應用最核心的部分,其中包含了讀取數據,驗證數據,執行支付,發送電子郵件,還有程序里所有其他功能的代碼。事實上,你的領域邏輯層不需要知道任何關于「Web」的事情!Web 層僅僅是一種訪問應用程序的傳輸機制,關于 Web 和 HTTP 請求的一切不應該超出路由和控制器層的范圍。做出好的架構設計的確很有挑戰性,但好的架構設計也會帶來可維護的、更加清晰的代碼。 舉個例子,與其在業務邏輯類里面直接獲取 Web 請求,不如把 Web 請求通過控制器傳遞給業務邏輯類。這個簡單的改動會將你的業務邏輯類和「Web」層解耦,并且不必擔心怎么去模擬 Web 請求,就可以輕松測試業務邏輯類: ```php class BillingController extends BaseController { public function __construct(BillerInterface $biller) { $this->biller = $biller; } public function postCharge(Request $request) { $this->biller->chargeAccount(Auth::user(), $request->input('amount')); return view('charge.success'); } } ``` 現在 `chargeAccount` 方法更容易測試了,由于我們不再需要在 `BillerInterface` 實現類中使用 `User` 和 `Request` 類,只需將用戶和金額傳遞到該方法即可。 編寫可維護性應用程序的關鍵之一,就是職責分離。要時常檢查一個類是否管得太寬,知道一些它不該知道的。你要常常問自己「這個類是否需要關心X?」如果答案是否定的,那么就要把這塊邏輯提取出來放到另一個類里面,然后用依賴注入的方式將其注入進來。 > 如何判斷一個類是否管得太寬?一個有用的方法就是檢查你為什么要改這塊代碼。舉個例子,當我們想調整通知邏輯的時候,是否需要修改 `Biller` 的實現代碼?當然不需要,`Biller` 實現只關注支付,它與通知邏輯應當僅通過契約來進行交互。在處理代碼時使用這種思路,可以幫助你快速找出應用中需要改進的地方。 ### 東西都放哪兒? 當通過 Laravel 開發應用時,你可能會困惑于應該把各種「東西」放在哪里。例如,輔助函數要放在哪里?事件監聽器要放在哪里?視圖組件要放在哪里?答案可能出乎你的意料 —— 「隨便,放哪兒都行!」Laravel 并沒有很多關于這方面的文件系統上的約定。不過,這個答案的確不能讓人滿意,所以下面我們就這個問題展開討論,一起探討這些「東西」究竟可以放在哪里。 #### 輔助函數 我們可以在 `app` 目錄下創建一個 `helpers.php` 文件,然后將自定義的輔助函數都放到這個文件中。當然,由于這個文件里面包含的不是類,不適合通過命名空間引用其中的函數,需要在 `composer.json` 中全局注冊它: ```php "autoload": { ... "files": [ "app/helpers.php" ] }, ``` 然后運行 `composer dump-auto` 重新注冊自動加載映射關系。然后就可以在應用中使用 `app/helpers.php` 中定義的輔助函數了。 #### 事件監聽器 事件監聽器當然不該放到 `routes.php` 文件里面,所以我們要找另外的地方來存放。事實上,在 Laravel 5.* 中,當我們通過 `php artisan make:listener` 命令創建時間監聽器時,系統會自動在 `app` 目錄下創建 `Listeners` 子目錄,并將生成的監聽器類放到該目錄下。所以我們對于自定義的事件監聽器類,放到該目錄下即可。 #### 錯誤處理器 在 Laravel 5.* 版本中,默認情況下所有的異常都是通過 `App\Exceptions\Handler` 來處理的,你也可以通過自定義的異常類來處理,自定義異常類可以放到 `app/Exceptions` 目錄下。 #### 其他 通常,只要遵循 PSR-4 規范就可以在應用目錄結構中保持類的整齊。結合你目前為止學習到的知識,對于什么代碼要放在什么地方這個問題,應當可以給出一個有理有據的答案了。但永遠不要拒絕試驗。Laravel 的美妙之處就是你可以做出最適合你自己應用的約定。去探索和發現最適合你自己應用的結構吧,別忘了和他人分享你的見解! 例如,你可能受到我們之前例子的啟發,在 `QuickBill` 中創建一個 `Providers` 目錄來存放所有你自定義的服務提供者,目錄結構類似這樣: ```php // app // QuickBill // Billing // Extensions //Pagination -> Environment.php // Providers -> EventPusherServiceProvider.php // Repositories User.php Payment.php ``` 注意上面的例子,我們有 `Providers` 和 `Extensions` 兩個命名空間。所有你自定義的服務提供者都可以放到 `Providers` 命名空間下,而 `Extensions` 命名空間可以用來存放你對框架核心進行擴展的類。 > 學院君注:對于小型應用,不創建 `QuickBill` 目錄,直接在 `app` 目錄下創建相應的目錄存放也是 OK 的。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看