代碼整潔之道-對象和數據結構
- 2019 年 10 月 7 日
- 筆記
現在,有一個計算面積的需求,其中一種實現如下:
class Square{ public $side; } class Geometry{ public function area($shape){ if($shape instanceof Square){ return $shape->side * $shape->side; } return 0; } }
有人看了,你這抽象的有問題啊,很明顯是面向過程的,如果新加一個類型,Geometry類中的所有方法都要修改。嗯,卻是是這樣,但反過來想,如果新加一個方法,所有現有的形狀類都不用動,只要在Geometry類中添加方法就行了。
當然了,還有一種多態的實現方式:
class Square implements Shape{ private $side; public function area(){ return $this->side * $this->side; } }
你以為這樣就萬事大吉了?並沒有。確實這樣實現,添加新的類型,只要新鞋一個類實現方法即可,很簡單。但是如果要添加一個新的函數,那不好意思,所有的類都要進行修改。
簡單總結下,就是說:
- 過程式代碼便於在不改動現由數據結構的前提下添加新的函數,面向對象便於在不改動現由函數的前提先添加新的類型
- 過程式代碼難以添加新的數據結構,因為必須修改所有函數。面向對象代碼難以添加新函數,因為必須修改所有類
- 對象暴露行為,隱藏數據。便於添加新的數據類型而無需修改現有行為,同時也難以在現有對象中添加新的行為
- 數據結構(上面的第一種實現)暴露數據,沒有明顯的行為。便於向現有數據結構添加新行為,同時也難以向現有函數添加新的數據結構。
當然,具體使用哪一種還是應該靈活選擇,不必拘泥。
如果希望靈活添加新行為,就使用數據結構的方式。如果希望靈活添加新類型,就使用面向對象的方式。