函數(shù)式、oop 和命名空間--對(duì)于 destoon 代碼優(yōu)秀設(shè)計(jì)的思考 一

在這篇文章名字中使用優(yōu)秀是經(jīng)過我這兩天研究后決定的。
原因是我在使用了這么多年的`oop`后再見到`function`的驚訝。
正如我在一開始入門編程時(shí),僅會(huì)用 `html` 后來半推半就的了解了點(diǎn) `asp`,第一次看到別人的 `asp` 代碼用了函數(shù)定義一樣。
我也不知道文章會(huì)如何分,在未完成之前就隨手記吧。
# 通過對(duì)入口文件分析來說說 `oop` 和 `函數(shù)式` 的不同
1. 大部分的 `oop` 習(xí)慣于使用單入口,因?yàn)閱稳肟诟臃奖闾幚?,使用基類進(jìn)行處理讓系統(tǒng)更加完整,可以通過基類進(jìn)行解耦,不用過多關(guān)注業(yè)務(wù)邏輯之外的架構(gòu)。
2. 在看到 `destoon` 后讓我想到了 `discuz!`,當(dāng)年在使用論壇程序的時(shí)候我們就在用了這樣的方式。 總結(jié)特點(diǎn)如下:
? ? 1. 很少使用類,后者僅有部分內(nèi)容使用類(一般用類的也就是數(shù)據(jù)庫,這也是比較先進(jìn)的了,大部分仍然還是用函數(shù) 定一個(gè)全局變量)
? ? 2. 函數(shù)思想,所有的方法封裝成函數(shù)
? ? 3. 變量,通用全局變量。通過將大部分的變量定義成全局變量來進(jìn)行處理變量的變化。
? ? 4. 目錄結(jié)構(gòu),由于函數(shù)式維護(hù)的復(fù)雜性,更多的人在寫此類框架的將結(jié)構(gòu)定義的非常明確。這種方式其實(shí)與`命名空間`比較類似。定義公共的模塊路徑,入口文件通過條件判斷來引入不同的模塊下的相同定義名的文件。
3. 暫且不說 `discuz!` 單入口解決方案。我這里研究了下 `destoon` 的分站解決方案。`destoon`的分站首頁和主站首頁用了相同的入口文件?
? ? 1. 入口文件引入的公共文件 `common.inc.php` 定義幾個(gè)變量 `$city_domain = $city_template = $city_sitename = '';`
? ? 2. 如果開啟了分站 `$DT['city'] ` 為0 未開啟 為1 開啟? 這里使用了緩存 導(dǎo)致比較難以明確 `$DT['city']`的來源? 具體可以通過查看 `cache_module()` 方法來確認(rèn)。
? ? 3. 如果開啟分站則加載分站處理公共腳本`city.inc.php`;
? ? 4. 通過匹配域名 `getenv('http_host')`來獲取到網(wǎng)站訪問域名,然后去 `city`表中查詢域名對(duì)應(yīng)的分站,如果存在則,將表查詢的 `id` 賦給 `cityid`,來確定有分站。
? ? 5. 通過 `cityid` 再次得到分站信息然后賦值? ? ??
? ? ```php
? ? $c = $db->get_one("SELECT * FROM {$DT_PRE}city WHERE areaid=$cityid");
? ? $city_name = $c['name'];
? ? $city_domain = $c['domain'];
? ? $city_template = $c['template'];
? ? ```
? ? 6. 得到了城市分站相關(guān)信息模板設(shè)置,然后就是堵數(shù)據(jù)處理模板了。
4. 通過3的分析,再次讓我感受到了`destoon`作者設(shè)計(jì)的苦心。我們?cè)谟胉oop`在基類中的構(gòu)造方法中也是完成這一套邏輯。同樣跟`oop`對(duì)比后,我們發(fā)現(xiàn)我們對(duì)于`oop`的認(rèn)同感增強(qiáng)了,而對(duì)于函數(shù)式這種寫法也更加排斥。 因?yàn)槟悴恢滥硞€(gè)變量來自于哪里,尤其是我們用`extract($array)`后的崩潰感。
#命名空間與函數(shù)和變量隔離
1. 在函數(shù)式中我們沒法定義兩個(gè)相同名稱的`funciton`;
2. 在`oop`中我們可以在不同的類中定義相同名稱的 `function`,但是在公共函數(shù)文件中仍然跟函數(shù)式一樣無法定義相同名稱的`function`;
3. 命名空間的出現(xiàn)讓我們避免了這個(gè)問題。當(dāng)我們對(duì)一個(gè) `php` 語言文件頂部增加`namespace Foo;`的時(shí)候,我們就將這個(gè)文件劃分到了 `Foo` 空間下。如下面對(duì)的代碼.??
```php
namespace Foo;
function base64_urlSafeEcode($data){
? ? $find = ['+', '/'];
? ? $replace = ['-', '_'];
? ? return str_replace($find, $replace, base64_encode($data));
}
```
? 這個(gè)時(shí)候我們調(diào)用 `base64_urlSafeEcode()`的時(shí)候需要使用 `\Foo\base64_urlSafeEcode()`;當(dāng)然可以將這個(gè)方法明明為`base64_encode()`。之所以定義不同名稱是為了更好讓人理解,這個(gè) `base64` 編碼方法是`url 安全`的。