PHP8 - Release Note - 字串與數字的比對行為修正
PHP8 - Release Note - 字串與數字的比對行為修正前言在 PHP8 官方的 release 網頁中,看到一個似乎更新風險相當大的一個改動,如圖
同樣的比對會回傳不一樣的結果,感覺很可能導致很多產品的比較或是套件內的比較失效。我對於這樣的差異性感到好奇,照常理來說 PHP8 的結果會比較貼近於直覺,而 PHP8 以前為什麼會是那樣的結果呢? PHP8 做的這種更動,影響的範圍會不會比想像中還要更大呢?
所以我看了這個更新的 RFC ,以下會大致上以 RFC 的內容嘗試著去解釋差異性的前因後果。
PHP8 之前的字串與數字比對PHP8 以前的數字與字串比對是甚麼樣子的呢?是甚麼樣的運作會導致以下的結果呢?
10 == 'foobar'; // bool(true)
PHP 將比較的運算子分為兩種:
Strict(嚴格) : === 、 !==
Non-strict(寬鬆) : == 、 != 、 > 、 >= 、 < 、 < ...
Working Effectively with Legacy Code - Ch3 - 感測和分離
Working Effectively with Legacy Code - Ch3 - 感測和分離通常來說,我們想要將測試安置到位,有兩個理由去解除依賴:
感測:有時候我們想測試的類別會對其他類別做出影響,我們就需要透過解除依賴去「感測」這些影響
分離:當我們無法將一部份的程式碼放入測試工具中去執行時,通常需要透過解除依賴將這塊程式碼「分離」出來
通常來說,這兩個面向是伴隨著彼此而出現的,試想因為一部分的程式碼無法被測試,所以我就將這部分給分離出來,而他獨立出來後,或許class之間的互動就成為了新的測試議題,我們便會想要感測分離出來的class是否被正確的影響。
本書提及了相當多的解除依賴技術,而在這之中最主要的一項技術是:偽裝成合作者(fake object)
偽裝成合作者偽物件偽物件就是那些在測試中,用來代替被測試的類別的「合作者」的物件。底下我們看一個例子。
假設在一個POS系統中有一個 Sale 類別(如下圖),Sale中含有一個 scan 的 function,當我們要掃條碼的時候就會呼叫這個 function,並且呼叫之後會在收銀機上顯示商品的名稱及價格。
那麼我 ...
Working Effectively with Legacy Code - Ch2 - 帶著回饋工作
Working Effectively with Legacy Code - Ch2 - 帶著回饋工作對系統進行變動,主要有兩種模式
編輯並祈禱(edit and pray)
覆蓋並修改(cover and modify)
編輯並祈禱(edit and pray)
Software and cathedrals are much the same – first we build them, then we pray.(Sam Redwine [Proceedings of the 4th International Software Process Workshop, Moretonhampstead, Devon, U.K., 11–13 May 1988, IEEE Computer Society])
軟體和教堂非常相似——建成之後我們就開始祈禱。(Sam Redwine)
仔細的計畫要做的更動,並確保自己理解要修改的程式碼,這一系列的動作看似細心謹慎且需要高度專業,但卻對於不變的部分卻缺乏任何工程手段去掌握,無法做出任何保證。通常在完成變更後,我們還需要大量的時間去 ...
Working Effectively with Legacy Code - Ch1 - 修改軟體
Working Effectively with Legacy Code - Ch1 - 修改軟體前言本書的書名叫做「管理、修改、重構遺留程式碼的藝術」,那麼什麼是「遺留程式碼」呢?
普遍上來說的遺留程式碼的定義為:遺留程式碼就是指從其他人那裡得來的程式碼
而作者對於「遺留程式碼」的定義卻不盡然
作者認為的遺留程式碼定義為:沒有編寫測試的程式碼
作者表示他想透過這本書闡述以下的想法
沒有編寫測試的程式碼是糟糕的程式碼,不管我們多麼細心地去編寫它們,不管它們有多漂亮、物件導向或封裝良好。有了測試,我們就能夠迅速的、可驗證地修改程式碼的行為。沒有測試,我們就不知道修改後的程式碼,實際上是變得更好還是更糟。
以下開始進入第一章正式的內容。
修改軟體的四個起因一般來說,我們可以將修改軟體的起因區分為以下四大類
添加新特性
修正bug
改善設計
最佳化資源使用
添加特性和修正bug添加特性與修正Bug常常是相輔相成出現的,只差別在主觀上的認定(工程面及業務面),作者認為其中最為重要的是,軟體的對外行為做出改變了。
改善設計其實就是我們所知的重構(Refactoring),在不改變 ...
SQL達人的現場工作筆記 - Ch4 - 三元邏輯運算與NULL
SQL達人的現場工作筆記 - Ch4 - 三元邏輯運算與NULLIntro一般來說,普遍上的程式語言都會有布林值的資料類型(bool、boolean),可以用作二元邏輯的判斷或是運算,而 SQL 除了 true 、 false 以外還另外追加了 unknown 這個第三值。所以 SQL 體系中,我們稱這種邏輯體系為三元邏輯(three-valued logic)。
起因是由於關連式資料庫的體系中具有 NULL 這個值,所以運算的時候必須將其納入考慮,也因為三元邏輯的判斷有時候相當詭異,所以常常會伴隨著一些很怪的結果。
理論篇你知道嗎?其實有兩種NULL。那到底是三元邏輯還是四元邏輯?兩種 NULL 分別是
Unknown 未知值
我們無法得知某個戴太陽眼鏡的人的眼睛顏色,這種叫做「未知值」,他有這個屬性,但我們不知道
Not Applicable, Inapplicable 不適性值
像是冰箱的眼睛顏色,由於他本身並不賦予這種屬性,我們無論如何都無法得知,這種叫做「不適性值」常常在表格中看到的 N/A 符號,就是 Not Applicable 的縮寫
雖然說有兩種 ...
Design Patterns - Behavioral - Memento Pattern 備忘錄模式
設計模式 - Memento Pattern 備忘錄模式Intro假設今天我們想製作一個可以”上一步”的編輯器
實作為了顧及功能的靈活性,我們做了一些分工我們建立一個IDE的class(IDEOriginator),讓他掌管原本IDE該有的所有功能再來我們需要一個儲存狀態的class(Memento),讓我們可以把IDE的狀態變成某種資料格式儲存起來最後既然我們需要將IDE的狀態儲存起來,我們再新增一個可以管理儲存內容的class(CareTaker)接著來看看怎麼將他一步一步建構出來吧
首先,我們看一下IDEOriginator除了他的原本的功能外,我們為了儲存狀態及設定狀態多給了他2個function
createMemento : 將現在IDE的狀態轉化為一個Memento物件,讓這個物件負責掌管IDEOriginator的參數設定
setMemento : 可以將Memento輸入,並且將IDEOriginator的參數全部設定為Memento所記錄的樣子
12345678910111213141516171819202122232425262728class IDEOri ...
Design Patterns - Behavioral - Chain of Responsibility Pattern 職責鏈模式
設計模式 - Chain of Responsibility Pattern 職責鏈模式Intro假設我們今天要設計一個流程,當處理人處理不來的時候則轉交給下一個處理的人
例如今天產品出了問題小問題的話CEO就可以唬兩句就解決了但如果問題大一點的話,可能就要靠經理出來圓個場但如果今天問題更大的話,那只好摘贓底下的工程師,讓工程師加班來解決問題
以下我們來實作一下這個處理流程的程式
實作我們先定義一下出問題的類別,好讓各階層處理的人員可以判斷這個問題有多大條
1234567891011class Trouble{ private $Level; public function __construct(int $Level) { $this->Level = $Level; }}
我們希望每個腳色都有一個固定的介面可以去處理問題,所以這邊我們先新增一個抽象類別Handler,讓他制定一個handleTrouble方法,讓外部知道我們只要去使用這個方法就可以解決問題。另外因為處理不來的事情我們就要丟包給下一 ...
Design Patterns - Behavioral - Mediator Pattern 仲介者模式
設計模式 - Mediator Pattern 仲介者模式Intro當很多物件互相需要協作的時候,物件間的耦合關係常常會變得比較混亂假設我們有三個國家的人在共同會議上需要傳訊息,但因為語言的隔閡,他們只能私訊另外兩個國家的人,並且貼上他們翻譯過後的文字,他們的互動關係會像下面這樣
但是如果今天有一個相當厲害的翻譯人員協助的話,我們就只要將自己的話告訴翻譯人員,他就會幫我們翻譯並且轉述給另外兩個國家的人了,加入了翻譯人員的互動關係會像下面這樣
讓某個腳色在中間為各種物件做協調,這就是仲介者模式的初始的想法
實作首先我們新增中介者的介面Mediator我們希望他可以扮演傳訊息給其他使用者的腳色,所以制定了一個sendToOther方法
123456interface Mediator{ public function sendToOther(string $country_user, string $message): array;}
再來我們定義一個抽象類別Colleague,這個腳色他必須知道要把訊息傳給誰,讓誰來擔任中介者,所以制定了一個Mediato ...
Design Patterns - Structural - Composite Pattern 組合模式
設計模式 - Composite Pattern 組合模式Intro假設我們今天要建構一個可以代表公司與部門之間結構的關係,公司可以包含分公司、可以包含部門,而部門可以包含子部門或是員工。
實作我們先建立一個Component類別,讓它具有可以擴充及移除的功能,且期望所有他的子類別都能夠有固定的行為(operation)
123456789101112131415abstract class Component{ protected $name; public function __construct(string $name) { $this->name = $name; } abstract public function add(Component $component); abstract public function remove(Component $component); abstract public function operation();}
再來我們新 ...
SOLID - Dependency Inversion Principle - 依賴反轉轉原則
SOLID - DIP (1) - DIP 與 IoCDependency Inversion Principle - 依賴反轉轉原則首先,我們先來看一段關於依賴反轉原則的敘述
定義wiki
A.High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g. interfaces).B.Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.
A. 高階模組不應該依賴低階模組,兩者都應該依賴於抽象(例如interface)B. 抽象不應該依賴於具體,而具體實現應該依賴於抽象介面
如果你像我一樣看完之後一頭霧水的話,這邊應該大致上會產生幾個疑問
什麼是高階模組?什麼又是低階模組?
什麼是具體?什麼是抽象?
什麼是依賴?
什麼是抽象依賴於具體?
什麼是具體依賴於抽象?
依賴反轉? 先了解 ...