代碼整潔之道-對象和數據結構

  • 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;      }  }

你以為這樣就萬事大吉了?並沒有。確實這樣實現,添加新的類型,只要新鞋一個類實現方法即可,很簡單。但是如果要添加一個新的函數,那不好意思,所有的類都要進行修改。

簡單總結下,就是說:

  • 過程式代碼便於在不改動現由數據結構的前提下添加新的函數,面向對象便於在不改動現由函數的前提先添加新的類型
  • 過程式代碼難以添加新的數據結構,因為必須修改所有函數。面向對象代碼難以添加新函數,因為必須修改所有類
  • 對象暴露行為,隱藏數據。便於添加新的數據類型而無需修改現有行為,同時也難以在現有對象中添加新的行為
  • 數據結構(上面的第一種實現)暴露數據,沒有明顯的行為。便於向現有數據結構添加新行為,同時也難以向現有函數添加新的數據結構。

當然,具體使用哪一種還是應該靈活選擇,不必拘泥。

如果希望靈活添加新行為,就使用數據結構的方式。如果希望靈活添加新類型,就使用面向對象的方式。