詳解Composer+Git怎么創(chuàng)建 “服務(wù)類庫(kù)”

本文由composer教程欄目給大家介紹Composer 怎么結(jié)合 git 來(lái)創(chuàng)建 “服務(wù)類庫(kù)”,希望對(duì)需要的朋友有所幫助!

導(dǎo)語(yǔ)

我一直認(rèn)為,現(xiàn)在的 php 已經(jīng)進(jìn)展到了工程化的領(lǐng)域。以前的 PHP 開發(fā)者,以快為美,速度和規(guī)模永遠(yuǎn)都是矛盾體。現(xiàn)在的 PHP 項(xiàng)目,特別是稍微大型一點(diǎn)的項(xiàng)目中,已經(jīng)在逐漸演化成為需要兼顧工程化和規(guī)模化的層次了。一個(gè)代碼工程化,就意味著演化為逐漸復(fù)雜的架構(gòu)。復(fù)雜的架構(gòu),微服務(wù)往往就是一個(gè)很好的選擇。

我在最近的一個(gè)項(xiàng)目中,就需要這個(gè)問(wèn)題。我需要開發(fā)一個(gè)地圖服務(wù),這個(gè)服務(wù)當(dāng)然不是簡(jiǎn)單的類庫(kù)形式,而是有自己的數(shù)據(jù)庫(kù),自己的服務(wù)接口。這種情況其實(shí)最優(yōu)的選擇就是服務(wù)化。服務(wù)化的方式當(dāng)然有很多了,Thrift,http 等。但是我評(píng)估了下當(dāng)前的部門環(huán)境,PHP 是主流的語(yǔ)言,加上自己這個(gè)項(xiàng)目的進(jìn)度也比較緊,在我眼中,Thrift,Http 等方式都是使用網(wǎng)絡(luò)協(xié)議實(shí)現(xiàn)服務(wù)的解耦合,這在我看來(lái)已經(jīng)是重度解決方案了。我覺(jué)得在項(xiàng)目沒(méi)有明確清晰病入膏肓的情況下是沒(méi)有必要這種方式的。使用網(wǎng)絡(luò)協(xié)議服務(wù)化的劣勢(shì)在于引入了強(qiáng)大的復(fù)雜度。這個(gè)復(fù)雜度往往意味著人力,物力,時(shí)間上的投入。所以我希望,能夠提供一個(gè) PHP 語(yǔ)言的 “服務(wù)類庫(kù)” 的形式進(jìn)行開發(fā)。

我想到的就是 PHP 的 Composer。

Composer 的修改

創(chuàng)建服務(wù)類庫(kù)

首先,我需要把我的 “服務(wù)類庫(kù)” 從我的應(yīng)用程序(起名為 xxx/main1)中獨(dú)立出來(lái),這個(gè)獨(dú)立,我不是選擇在應(yīng)用程序中創(chuàng)建一個(gè)目錄(事實(shí)我想過(guò)創(chuàng)建一個(gè)諸如 Services 的目錄)。但是,如果和業(yè)務(wù)程序在代碼上耦合起來(lái),我覺(jué)得以人的惰性,很難從始至終都控制住自己能堅(jiān)持不使用應(yīng)用程序中方便的各種函數(shù)。所以我的選擇是在 Git 庫(kù)中新創(chuàng)建一個(gè)項(xiàng)目,起名為 xxx/mapService 。

composer.json

現(xiàn)在兩個(gè) Git 項(xiàng)目(xxx/main1 和 xxx/mapService),我在 main1 中的 composer.json 文件中增加下面的語(yǔ)句:

詳解Composer+Git怎么創(chuàng)建 “服務(wù)類庫(kù)”

而在 mapService 的 composer.json 如下:

詳解Composer+Git怎么創(chuàng)建 “服務(wù)類庫(kù)”

這個(gè)配置告訴 main1 項(xiàng)目,mapService 的 Git地址,需要使用的版本。

當(dāng)然需要注意下面幾點(diǎn):

  • dev-master 意思是直接使用 mapService 的master分支。如果 mapService 有其他的 tag,這里完全可以使用 tag 信息
  • repositories 是說(shuō)明項(xiàng)目的地址
  • 我這里的這個(gè)服務(wù)是放在我們公司自己搭建的 gitlab 上的
  • mapService 下面的 src 文件夾的命名空間為 xxxxxxxxMapService 并且支持 PSR-4
  • mapService 使用了 illuminate/database

最后使用 composer update -vvv 可以把我們需要的 mapService 下載下來(lái)放在 vendor 目錄下。

更新修改

我們現(xiàn)在編輯器在 main1 項(xiàng)目中,如果我們有對(duì) mapService 這個(gè)項(xiàng)目有進(jìn)行編輯修改,并且希望合并到 mapService 的 master 分支的化,就直接進(jìn)入 vender/xxx/mapService 目錄,進(jìn)行 Git 對(duì)應(yīng)的操作。這樣就可以進(jìn)行直接的代碼修改了。

獨(dú)立配置

這種結(jié)構(gòu)的組合方式只是完成了萬(wàn)里長(zhǎng)征的第一步。后續(xù)更為重要的是在編寫這個(gè)服務(wù)的時(shí)候,我需要時(shí)刻記住不使用 main1 的所有東西,這樣才能保持 mapService 的獨(dú)立性(獨(dú)立性是服務(wù)化的必要條件之一)。比如我第一個(gè)遇到的問(wèn)題就是配置文件需要獨(dú)立。

我的實(shí)現(xiàn)方式是直接在 mapService 中創(chuàng)建一個(gè) Config 類,這個(gè)類中直接寫死配置。

這里一直覺(jué)得這個(gè)配置文件的實(shí)現(xiàn)方式有點(diǎn)挫,因?yàn)檫@樣,這個(gè)配置文件就進(jìn)入到了 Git庫(kù)。但是確實(shí)沒(méi)有想到更好的方案了。laravel 中有通過(guò)實(shí)現(xiàn) ServiceProvider 將 Config 創(chuàng)建在 Laravel 的config 文件夾下的方式,但是這種方式僅僅只適用于 Laravel。沒(méi)有通用性。在另外一個(gè)方向,我想服務(wù)使用哪個(gè)數(shù)據(jù)庫(kù)這個(gè)本身也是服務(wù)的一部分,放在服務(wù)的 Git 庫(kù)中貌似也沒(méi)有什么。

目錄結(jié)構(gòu)

詳解Composer+Git怎么創(chuàng)建 “服務(wù)類庫(kù)”

目錄結(jié)構(gòu)如上

  • Configs 提供配置文件
  • Contracts 提供接口協(xié)議
  • Exceptions 提供異常
  • Supports 提供第三方方法或者類庫(kù)
  • Models 提供對(duì)數(shù)據(jù)庫(kù)的交互
  • Node.php 實(shí)現(xiàn)具體的接口

服務(wù)最重要的事情是接口協(xié)議。所以創(chuàng)建一個(gè)Contracts文件夾,將提供的服務(wù)接口化。

詳解Composer+Git怎么創(chuàng)建 “服務(wù)類庫(kù)”

接口的異常處理盡量使用異常,而不是錯(cuò)誤碼的方式進(jìn)行交互。而且這些異常盡量要自定義。這樣,在上層就有了統(tǒng)一處理的可能性。

思考

這個(gè)架構(gòu)模式我定位為 PHP 代碼層面服務(wù)化的模式。適用的場(chǎng)景應(yīng)該是:

  • 后期計(jì)劃服務(wù)化
  • 前期人力和思維都希望維持快速開發(fā)的場(chǎng)景

和 Git 的 SubTree 、SubModule 的區(qū)別

其實(shí)這三種方式說(shuō)到底都是將一個(gè)項(xiàng)目作為另外一個(gè)項(xiàng)目的類庫(kù)來(lái)使用的。SubTree 和 SubModule 是 Git 的解決方案。而 Composer 是 PHP 語(yǔ)言的解決方案,它除了將某個(gè)項(xiàng)目加入到另外一個(gè)項(xiàng)目的功能之外,還提供了加入版本,依賴解決等方案。如果你的項(xiàng)目是 PHP 的,那么無(wú)疑,使用 Composer 是更優(yōu)的選擇。

后期協(xié)議服務(wù)化

如果后期我的這個(gè) mapService 想要協(xié)議服務(wù)化,那么這個(gè) mapService 項(xiàng)目就可以簡(jiǎn)化成為一個(gè)SDK,對(duì)于上層業(yè)務(wù)邏輯,只需要使用 composer update 進(jìn)行更新就行。

服務(wù)注冊(cè)和發(fā)現(xiàn)

我這里所謂的 “服務(wù)類庫(kù)” 確實(shí)沒(méi)有解決服務(wù)注冊(cè)的問(wèn)題,我無(wú)法知道到底有幾個(gè)項(xiàng)目使用了我的服務(wù)。這個(gè)可能需要額外的流程的工作了。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊11 分享