SOLID:面向對象設計的前五項原則
- 2020 年 7 月 24 日
- 筆記
S.O.L.I.D代表:
-
S – 單一責任原則
-
O – 開閉原理
-
L – Liskov替代原理
-
I – 介面隔離原理
-
D – 依賴倒置原則
單一責任原則
一個類有且只能有一個因素使其改變,意思是一個類只應該有單一職責.
class Circle { public $radius; public function construct($radius) { $this->radius = $radius; } } class Square { public $length; public function construct($length) { $this->length = $length; } }
class AreaCalculator { protected $shapes; public function __construct($shapes = array()) { $this->shapes = $shapes; } public function sum() { // logic to sum the areas } public function output() { return implode('', array( "", "Sum of the areas of provided shapes: ", $this->sum(), "" )); } }
$shapes = array( new Circle(2), new Square(5), new Square(6) ); $areas = new AreaCalculator($shapes); echo $areas->output();
$shapes = array( new Circle(2), new Square(5), new Square(6) ); $areas = new AreaCalculator($shapes); $output = new SumCalculatorOutputter($areas); echo $output->JSON(); echo $output->HAML(); echo $output->HTML(); echo $output->JADE();
開閉原理
對象和實體應該對擴展開放,但是對修改關閉。
public function sum() { foreach($this->shapes as $shape) { if(is_a($shape, 'Square')) { $area[] = pow($shape->length, 2); } else if(is_a($shape, 'Circle')) { $area[] = pi() * pow($shape->radius, 2); } } return array_sum($area); }
class Square { public $length; public function __construct($length) { $this->length = $length; } public function area() { return pow($this->length, 2); } }
public function sum() { foreach($this->shapes as $shape) { $area[] = $shape->area(); } return array_sum($area); }
interface ShapeInterface { public function area(); } class Circle implements ShapeInterface { public $radius; public function __construct($radius) { $this->radius = $radius; } public function area() { return pi() * pow($this->radius, 2); } }
public function sum() { foreach($this->shapes as $shape) { if(is_a($shape, 'ShapeInterface')) { $area[] = $shape->area(); continue; } throw new AreaCalculatorInvalidShapeException; } return array_sum($area); }
Liskov替代原則
如果對每一個類型為 T1 的對象 o1,都有類型為 T2 的對象 o2,使得以 T1 定義的所有程式 P 在所有的對象 o1 都代換成 o2 時,程式 P 的行為沒有發生變化,那麼類型 T2 是類型 T1 的子類型。
class VolumeCalculator extends AreaCalulator { public function construct($shapes = array()) { parent::construct($shapes); } public function sum() { // logic to calculate the volumes and then return and array of output return array($summedData); } }
class SumCalculatorOutputter { protected $calculator; public function __constructor(AreaCalculator $calculator) { $this->calculator = $calculator; } public function JSON() { $data = array( 'sum' => $this->calculator->sum(); ); return json_encode($data); } public function HTML() { return implode('', array( '', 'Sum of the areas of provided shapes: ', $this->calculator->sum(), '' )); } }
$areas = new AreaCalculator($shapes); $volumes = new AreaCalculator($solidShapes); $output = new SumCalculatorOutputter($areas); $output2 = new SumCalculatorOutputter($volumes);
public function sum() { // logic to calculate the volumes and then return and array of output return $summedData; }
介面隔離原理
使用方(client)不應該依賴強制實現不使用的介面,或不應該依賴不使用的方法。
interface ShapeInterface { public function area(); public function volume(); }
interface ShapeInterface { public function area(); } interface SolidShapeInterface { public function volume(); } class Cuboid implements ShapeInterface, SolidShapeInterface { public function area() { //計算長方體的表面積 } public function volume() { // 計算長方體的體積 } }
interface ManageShapeInterface { public function calculate(); } class Square implements ShapeInterface, ManageShapeInterface { public function area() { /Do stuff here/ } public function calculate() { return $this->area(); } } class Cuboid implements ShapeInterface, SolidShapeInterface, ManageShapeInterface { public function area() { /Do stuff here/ } public function volume() { /Do stuff here/ } public function calculate() { return $this->area() + $this->volume(); } }
依賴倒置原則
實體必須依賴於抽象而不依賴於具體。它指出高級模組一定不能依賴於低級模組,而應該依賴於抽象。
class PasswordReminder { private $dbConnection; public function __construct(MySQLConnection $dbConnection) { $this->dbConnection = $dbConnection; } }
interface DBConnectionInterface { public function connect(); }
class MySQLConnection implements DBConnectionInterface { public function connect() { return "Database connection"; } } class PasswordReminder { private $dbConnection; public function __construct(DBConnectionInterface $dbConnection) { $this->dbConnection = $dbConnection; } }
結論
interface ManageShapeInterface { public function calculate();}
class Square implements ShapeInterface, ManageShapeInterface { public function area() { /Do stuff here/ }
public function calculate() { return $this->area(); }}
class Cuboid implements ShapeInterface, SolidShapeInterface, ManageShapeInterface { public function area() { /Do stuff here/ } public function volume() { /Do stuff here/ }
public function calculate() { return $this->area() + $this->volume(); }}